TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Performance Tuning for .NET Core

182 点作者 benaadams超过 6 年前

7 条评论

rhinoceraptor超过 6 年前
It would be nice if .NET Core profiling was a bit easier on Linux, Microsoft has a shell script[1] to do profiling but it requires Windows only tools.<p>They don&#x27;t ship Crossgen with the Linux packages, and you have to manually generate the .NET runtime symbols.<p>I&#x27;ve gotten things like FlameGraphs working using BCC profile[2], but it took quite a bit of work.<p>[1]: <a href="https:&#x2F;&#x2F;raw.githubusercontent.com&#x2F;dotnet&#x2F;corefx-tools&#x2F;master&#x2F;src&#x2F;performance&#x2F;perfcollect&#x2F;perfcollect" rel="nofollow">https:&#x2F;&#x2F;raw.githubusercontent.com&#x2F;dotnet&#x2F;corefx-tools&#x2F;master...</a> [2]: <a href="https:&#x2F;&#x2F;github.com&#x2F;iovisor&#x2F;bcc&#x2F;blob&#x2F;master&#x2F;tools&#x2F;profile.py" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;iovisor&#x2F;bcc&#x2F;blob&#x2F;master&#x2F;tools&#x2F;profile.py</a>
评论 #18914849 未加载
kevingadd超过 6 年前
A tip related to the throw inlining tip: One way to get more consistent&#x2F;effective inlining is to split the complex &#x27;slow paths&#x27; out of your functions into helper functions. For example, let&#x27;s say you have a cached operation with cache hit and cache miss paths:<p><pre><code> void GetValue (string key, out SomeBigType result) { if (_cache.TryGetValue(key, out result)) return; result = new SomeBigType(key, ...); _cache[key] = result; } </code></pre> In most scenarios this function might not get inlined, because the cache miss path makes the function bigger. If you use the aggressive inlining attribute you might be able to convince the JIT to inline it, but once the function gets bigger it doesn&#x27;t inline anymore.<p>However, if you pull the cache miss out:<p><pre><code> void GetValue (string key, out SomeBigType result) { if (_cache.TryGetValue(key, out result)) return; GetValue_Slow(key, out result); } void GetValue_Slow (string key, out SomeBigType result) { result = new SomeBigType(key, ...); _cache[key] = result; } </code></pre> You will find that in most cases, GetValue is inlined and only GetValue_Slow produces a function call. This is especially true in release builds and you can observe it in the built-in Visual Studio profiler or by looking at method disassembly.<p>(Keep in mind that many debuggers - including VS&#x27;s - will disable JIT optimization if you start an application under the debugger or attach to it. You can disable this.)<p>This tip applies to both desktop .NET Framework and .NET Core, in my testing (netcore is generally better at inlining, though!) If you&#x27;re writing any performance-sensitive paths in a library I highly recommend doing this. It can make the code easier to read in some cases anyway.
gameswithgo超过 6 年前
One of the tips is to avoid Linq, which many .NET developers are hesitant to do. I made a library that lets you use Linq style convenience functions without a performance hit in many cases:<p><a href="https:&#x2F;&#x2F;github.com&#x2F;jackmott&#x2F;LinqFaster" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;jackmott&#x2F;LinqFaster</a>
评论 #18915742 未加载
评论 #18914789 未加载
评论 #18915027 未加载
评论 #18914743 未加载
评论 #18920349 未加载
评论 #18914498 未加载
评论 #18918650 未加载
zamalek超过 6 年前
&gt; Reduce branching &amp; branch misprediction<p>I wrote a parser for a &quot;formalized&quot; URI (it looked somewhat like OData). This parser was being invoked millions of times and was adding minutes to an operation - it dominated the profile at something like 30% CPU time. It started off something like this:<p><pre><code> int state = State_Start; for (var i = 0; i &lt; str.Length; i++) { var c = str[i]; switch (state) { case State_Start: &#x2F;* Handle c for this state. *&#x2F; &#x2F;* Update state if a new state is reached. *&#x2F; } } </code></pre> Hardly rocket science, a clear-as-day miniature state machine. VTune was screaming about the switch, so I changed it to this:<p><pre><code> for (var i = 0; i &lt; str.Length; i++) { for (; i &lt; str.Length; i++) { var c = str[i]; &#x2F;* Handle c for this state. *&#x2F; &#x2F;* Break if a new state is reached. *&#x2F; } for (; i &lt; str.Length; i++) { var c = str[i]; &#x2F;* Handle c for this state. *&#x2F; &#x2F;* Break if a new state is reached. *&#x2F; } } </code></pre> The new profile put the function at &lt; 0.1% of CPU time. This is something that the &quot;premature optimization crowd&quot; (who tend to partially quote Knuth concerning optimization) get wrong: death by a thousand cuts. A <i>single</i> branch in the source (it ends up being more in machine code) was costing 30% performance.
评论 #18914060 未加载
评论 #18914091 未加载
GordonS超过 6 年前
&gt; Mark classes as sealed by default<p>Please, no! This shouldn&#x27;t be the <i>default</i> - it&#x27;s a constant bugbear of mine where I want to extend a class from a library, and I can&#x27;t because it&#x27;s been sealed for no good reason.
评论 #18914572 未加载
评论 #18914605 未加载
评论 #18914387 未加载
评论 #18914504 未加载
评论 #18914665 未加载
评论 #18914326 未加载
评论 #18914700 未加载
blinkingled超过 6 年前
&gt; JIT won&#x27;t inline functions that throw<p>Seriously? Never had to worry about that in Java land. What would be the reason for this?
评论 #18915907 未加载
评论 #18914753 未加载
jermaustin1超过 6 年前
So in other words extreme tuning = do the opposite of what you probably did!