TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Performance Tuning for .NET Core

182 pointsby benaadamsover 6 years ago

7 comments

rhinoceraptorover 6 years ago
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 未加载
kevingaddover 6 years ago
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.
gameswithgoover 6 years ago
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 未加载
zamalekover 6 years ago
&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 未加载
GordonSover 6 years ago
&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 未加载
blinkingledover 6 years ago
&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 未加载
jermaustin1over 6 years ago
So in other words extreme tuning = do the opposite of what you probably did!