{"@attributes":{"version":"2.0"},"channel":{"title":"Code Thoughts","description":"Thoughts on code","link":"https:\/\/jackmott.github.io\/\/","pubDate":"Tue, 14 Aug 2018 20:05:02 +0000","lastBuildDate":"Tue, 14 Aug 2018 20:05:02 +0000","generator":"Jekyll v3.7.3","item":[{"title":"Does Your Code Leave a Trail of Slowness?","description":"<h1 id=\"the-trail-of-slowness\">The Trail of Slowness<\/h1>\n\n<p>Often I implore people to make better performing coding decisions when the downsides\nare small or nonexistent. A common response to this is that you should only worry\nabout performance when you have measured the code in question and found performance to \nbe an issue.  There a couple of problems with that ethos, the first of which is that\nsometimes early decisions will be hard to reverse late in a project if performance turns\nout to be an issue. But there is a more insidious problem.  Areas of your code for which\nperformance is not important, may be causing <em>other<\/em> code, or even <em>other programs<\/em> to slow\ndown. This trail of slowness left behind by uninformed performance decisions will not\nshow up in any particular place in a profiler, they will just slow down everything a bit.<\/p>\n\n<h1 id=\"why-does-this-happen\">Why Does This Happen<\/h1>\n\n<p>Modern CPU performance is severely limited by RAM latency. A request to get data from RAM\ncan take over 100 CPU cycles to complete, and while your CPU waits, it just sits there, doing\nnothing useful. This problem is addressed by a series of caches in your CPU, smaller but much \nfaster regions of memory.  Whenever you request data from RAM, you get back an entire cache line\nof contiguous memory into the CPU caches.  Assuming that the next memory your request is in that\ncontiguous segment of memory in the cache line, you will get it very quickly.<\/p>\n\n<p>This is why iterating over an array in order (contiguous memory) is much, much faster than iterating over\na LinkedList, where each node is in a random(ish) location in the heap.  Many of those requests\nfrom RAM while iterating over a LinkedList miss the cache, and cause long CPU stalls.<\/p>\n\n<p>But it is worse than just being slow. Every time you request memory that isn\u2019t in the cache\nalready, you have to pull down a whole cache line and replace data that is already in the cache.  Any code running\nthat might have hoped to use that cached data won\u2019t have it, and will now have to get it from RAM\nagain.  This is sometimes called \u201cthrashing the cache\u201d.<\/p>\n\n<h1 id=\"how-bad-can-it-be\">How Bad Can It Be?<\/h1>\n\n<p>This can vary wildly based on the workloads involved. In the contrived example below, I do a \nfixed amount of work with a LinkedList, while at the same time I have other threads running\ndoing as much work as possible for 5 seconds. They are able to perform the ArraySumSquare function\nabout 3.5 million times in that 5 seconds.<\/p>\n\n<p>When I alter the RunLinkedList function to do the same fixed amount of work on arrays instead,\nthe original array loops are now able to perform ArraySumSquare about 4.4 million times.<\/p>\n\n<p>This could be similar to a situation where a server has a periodic computation it does, where\ntaking a few seconds isn\u2019t considered a problem at all.  But that job is having a significant\nimpact on users using the live system, increasing latency by a ~20%. Or it could be similar to a code editor that\nis doing some parsing behind the scenes where the performance seems fine when you profile it, but it is \nslowing down UI response due to the cache thrashing.<\/p>\n\n<h1 id=\"what-to-do\">What To Do<\/h1>\n\n<p>Use arrays or array backed lists by default unless you have good reasons not to. Most languages have resize-able array backed \nstructures that are as convenient to use as LinkedLists:<\/p>\n\n<ul>\n  <li>Java - ArrayList<\/li>\n  <li>C# - List<T><\/T><\/li>\n  <li>F# - ResizeArray (see FSharpX for higher order functions on these!)<\/li>\n  <li>C++ - std::vector<\/li>\n  <li>Rust - vec<\/li>\n<\/ul>\n\n<p>Even if you are inserting or removing from the front or middle of your collection periodically it is <a href=\"https:\/\/jackmott.github.io\/programming\/2016\/08\/20\/when-bigo-foolsya.html\">usually still faster overall<\/a>.  You may also\nconsider using a sorted array along with BinarySearch instead of a tree, when applicable.  Think about how you lay out your data structures,\navoid unnecessary pointer hops. Avoid virtual functions when they aren\u2019t really necessary. Understand how branch prediction works so you\ncan set your code up for success. <a href=\"https:\/\/www.akkadia.org\/drepper\/cpumemory.pdf\">Take some time to learn how memory works<\/a>, and you can make better default decisions, and better designs\nearly in your projects.<\/p>\n\n<h1 id=\"sample-code\">Sample Code<\/h1>\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">using<\/span> <span class=\"nn\">System<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">using<\/span> <span class=\"nn\">System.Collections.Generic<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">using<\/span> <span class=\"nn\">System.Diagnostics<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">using<\/span> <span class=\"nn\">System.Threading<\/span><span class=\"p\">;<\/span>\n\n<span class=\"k\">namespace<\/span> <span class=\"nn\">ConsoleApplication1<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">class<\/span> <span class=\"nc\">Program<\/span> <span class=\"p\">{<\/span>\n         \n        <span class=\"k\">static<\/span> <span class=\"k\">void<\/span> <span class=\"nf\">Main<\/span><span class=\"p\">(<\/span><span class=\"kt\">string<\/span><span class=\"p\">[]<\/span> <span class=\"n\">args<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n            <span class=\"n\">Thread<\/span> <span class=\"p\">[]<\/span> <span class=\"n\">arrayThreads<\/span> <span class=\"p\">=<\/span> <span class=\"k\">new<\/span> <span class=\"n\">Thread<\/span><span class=\"p\">[<\/span><span class=\"m\">8<\/span><span class=\"p\">];<\/span>\n            <span class=\"n\">Thread<\/span> <span class=\"p\">[]<\/span> <span class=\"n\">listThreads<\/span> <span class=\"p\">=<\/span> <span class=\"k\">new<\/span> <span class=\"n\">Thread<\/span><span class=\"p\">[<\/span><span class=\"m\">8<\/span><span class=\"p\">];<\/span>\n\n            <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"p\">&lt;<\/span> <span class=\"m\">8<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span><span class=\"p\">++)<\/span> <span class=\"p\">{<\/span>\n                <span class=\"n\">arrayThreads<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nf\">Thread<\/span><span class=\"p\">(<\/span><span class=\"n\">RunArray<\/span><span class=\"p\">);<\/span>\n                <span class=\"n\">listThreads<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nf\">Thread<\/span><span class=\"p\">(<\/span><span class=\"n\">RunLinkedList<\/span><span class=\"p\">);<\/span>\n                <span class=\"n\">arrayThreads<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">].<\/span><span class=\"nf\">Start<\/span><span class=\"p\">();<\/span>\n                <span class=\"n\">listThreads<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">].<\/span><span class=\"nf\">Start<\/span><span class=\"p\">();<\/span>\n            <span class=\"p\">}<\/span>\n\n            <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"p\">&lt;<\/span> <span class=\"m\">8<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span><span class=\"p\">++)<\/span> <span class=\"p\">{<\/span>\n                <span class=\"n\">arrayThreads<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">].<\/span><span class=\"nf\">Join<\/span><span class=\"p\">();<\/span>\n                <span class=\"n\">listThreads<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">].<\/span><span class=\"nf\">Join<\/span><span class=\"p\">();<\/span>                \n            <span class=\"p\">}<\/span>\n\n            <span class=\"n\">Console<\/span><span class=\"p\">.<\/span><span class=\"nf\">WriteLine<\/span><span class=\"p\">(<\/span><span class=\"s\">\"Perf Critical Ops:\"<\/span> <span class=\"p\">+<\/span> <span class=\"n\">totalOps<\/span><span class=\"p\">);<\/span>                        \n            <span class=\"n\">Console<\/span><span class=\"p\">.<\/span><span class=\"nf\">ReadLine<\/span><span class=\"p\">();<\/span>\n\n        <span class=\"p\">}<\/span>\n\n        <span class=\"k\">public<\/span> <span class=\"k\">static<\/span> <span class=\"kt\">int<\/span> <span class=\"n\">totalOps<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span>\n        <span class=\"k\">public<\/span> <span class=\"k\">const<\/span> <span class=\"kt\">int<\/span> <span class=\"n\">LEN<\/span> <span class=\"p\">=<\/span> <span class=\"m\">10000<\/span><span class=\"p\">;<\/span>\n        <span class=\"k\">public<\/span> <span class=\"k\">const<\/span> <span class=\"kt\">int<\/span> <span class=\"n\">TIME<\/span> <span class=\"p\">=<\/span> <span class=\"m\">5000<\/span><span class=\"p\">;<\/span>\n\n        <span class=\"k\">public<\/span> <span class=\"k\">static<\/span> <span class=\"k\">void<\/span> <span class=\"nf\">RunArray<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n            <span class=\"n\">Stopwatch<\/span> <span class=\"n\">sw<\/span> <span class=\"p\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nf\">Stopwatch<\/span><span class=\"p\">();<\/span>\n            <span class=\"n\">sw<\/span><span class=\"p\">.<\/span><span class=\"nf\">Start<\/span><span class=\"p\">();<\/span>\n            <span class=\"kt\">int<\/span><span class=\"p\">[]<\/span> <span class=\"n\">a<\/span> <span class=\"p\">=<\/span> <span class=\"k\">new<\/span> <span class=\"kt\">int<\/span><span class=\"p\">[<\/span><span class=\"n\">LEN<\/span><span class=\"p\">];<\/span>\n            <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"p\">&lt;<\/span> <span class=\"n\">a<\/span><span class=\"p\">.<\/span><span class=\"n\">Length<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span><span class=\"p\">++)<\/span> <span class=\"p\">{<\/span>\n                <span class=\"n\">a<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"m\">2<\/span><span class=\"p\">;<\/span>\n            <span class=\"p\">}<\/span>\n            <span class=\"kt\">long<\/span> <span class=\"n\">sum<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span>\n            <span class=\"kt\">int<\/span> <span class=\"n\">count<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span>\n            <span class=\"k\">while<\/span> <span class=\"p\">(<\/span><span class=\"n\">sw<\/span><span class=\"p\">.<\/span><span class=\"n\">ElapsedMilliseconds<\/span> <span class=\"p\">&lt;<\/span> <span class=\"n\">TIME<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>                \n                <span class=\"n\">sum<\/span> <span class=\"p\">+=<\/span> <span class=\"nf\">ArraySumSquare<\/span><span class=\"p\">(<\/span><span class=\"n\">a<\/span><span class=\"p\">);<\/span>\n                <span class=\"n\">count<\/span><span class=\"p\">++;<\/span>\n            <span class=\"p\">}<\/span>\n            <span class=\"n\">Interlocked<\/span><span class=\"p\">.<\/span><span class=\"nf\">Add<\/span><span class=\"p\">(<\/span><span class=\"k\">ref<\/span> <span class=\"n\">totalOps<\/span><span class=\"p\">,<\/span> <span class=\"n\">count<\/span><span class=\"p\">);<\/span>                        \n        <span class=\"p\">}<\/span>\n\n        <span class=\"k\">public<\/span> <span class=\"k\">static<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">ArraySumSquare<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span><span class=\"p\">[]<\/span> <span class=\"n\">a<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>                        \n            <span class=\"kt\">int<\/span> <span class=\"n\">sum<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span>\n            <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"p\">&lt;<\/span> <span class=\"n\">a<\/span><span class=\"p\">.<\/span><span class=\"n\">Length<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span><span class=\"p\">++)<\/span> <span class=\"p\">{<\/span>\n                <span class=\"n\">sum<\/span> <span class=\"p\">+=<\/span> <span class=\"n\">a<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span> <span class=\"p\">*<\/span> <span class=\"n\">a<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">];<\/span>\n            <span class=\"p\">}<\/span>\n            <span class=\"k\">return<\/span> <span class=\"n\">sum<\/span><span class=\"p\">;<\/span>\n        <span class=\"p\">}<\/span>\n\n        <span class=\"k\">public<\/span> <span class=\"k\">static<\/span> <span class=\"k\">void<\/span> <span class=\"nf\">RunLinkedList<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n            <span class=\"n\">Stopwatch<\/span> <span class=\"n\">sw<\/span> <span class=\"p\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nf\">Stopwatch<\/span><span class=\"p\">();<\/span>\n            <span class=\"n\">sw<\/span><span class=\"p\">.<\/span><span class=\"nf\">Start<\/span><span class=\"p\">();<\/span>\n            <span class=\"n\">LinkedList<\/span><span class=\"p\">&lt;<\/span><span class=\"kt\">int<\/span><span class=\"p\">&gt;<\/span> <span class=\"n\">l<\/span> <span class=\"p\">=<\/span> <span class=\"k\">new<\/span> <span class=\"n\">LinkedList<\/span><span class=\"p\">&lt;<\/span><span class=\"kt\">int<\/span><span class=\"p\">&gt;();<\/span>\n            <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"p\">&lt;<\/span> <span class=\"n\">LEN<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span><span class=\"p\">++)<\/span> <span class=\"p\">{<\/span>\n                <span class=\"n\">l<\/span><span class=\"p\">.<\/span><span class=\"nf\">AddLast<\/span><span class=\"p\">(<\/span><span class=\"m\">2<\/span><span class=\"p\">);<\/span>\n            <span class=\"p\">}<\/span>\n            <span class=\"kt\">long<\/span> <span class=\"n\">sum<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span>\n            <span class=\"kt\">int<\/span> <span class=\"n\">count<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span>\n            <span class=\"k\">while<\/span> <span class=\"p\">(<\/span><span class=\"n\">count<\/span> <span class=\"p\">&lt;<\/span> <span class=\"m\">75000<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n                <span class=\"n\">sum<\/span> <span class=\"p\">+=<\/span> <span class=\"nf\">LinkedListSumSquare<\/span><span class=\"p\">(<\/span><span class=\"n\">l<\/span><span class=\"p\">);<\/span>\n                <span class=\"n\">count<\/span><span class=\"p\">++;<\/span>\n            <span class=\"p\">}<\/span>            \n        <span class=\"p\">}<\/span>\n        \n        <span class=\"k\">public<\/span> <span class=\"k\">static<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">LinkedListSumSquare<\/span><span class=\"p\">(<\/span><span class=\"n\">LinkedList<\/span><span class=\"p\">&lt;<\/span><span class=\"kt\">int<\/span><span class=\"p\">&gt;<\/span> <span class=\"n\">l<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>            \n            <span class=\"kt\">int<\/span> <span class=\"n\">sum<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span>\n            <span class=\"k\">foreach<\/span> <span class=\"p\">(<\/span><span class=\"kt\">var<\/span> <span class=\"n\">num<\/span> <span class=\"k\">in<\/span> <span class=\"n\">l<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n                <span class=\"n\">sum<\/span> <span class=\"p\">+=<\/span> <span class=\"n\">num<\/span> <span class=\"p\">*<\/span> <span class=\"n\">num<\/span><span class=\"p\">;<\/span>\n            <span class=\"p\">}<\/span>\n            <span class=\"k\">return<\/span> <span class=\"n\">sum<\/span><span class=\"p\">;<\/span>\n        <span class=\"p\">}<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n","pubDate":"Mon, 27 Feb 2017 19:17:27 +0000","link":"https:\/\/jackmott.github.io\/\/2017\/02\/27\/trail-of-slow.html","guid":"https:\/\/jackmott.github.io\/\/2017\/02\/27\/trail-of-slow.html"},{"title":"PVS-Studio C#","description":"<p><a href=\"http:\/\/www.viva64.com\/en\/pvs-studio\/\">PVS-Studio<\/a> is a popular static analysis tool in the C++ world, and plenty of articles have been written about the kinds of\nbugs it can find in C++ projects, such as this entertaining one about the <a href=\"https:\/\/www.unrealengine.com\/blog\/how-pvs-studio-team-improved-unreal-engines-code\">Unreal Engine<\/a>.\nAbout year ago they added C# support, and have steadily been adding more C# analysis features since.  Today I grabbed version 6.10 and ran it on my code base at work, which\nis a fairly large ASP\/MVC web application.  Here are some of the things it found:<\/p>\n\n<h4 id=\"the-usergroup-object-was-used-before-it-was-verified-against-null\">The \u2018user.Group\u2019 object was used before it was verified against null<\/h4>\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>  <span class=\"kt\">var<\/span> <span class=\"n\">user<\/span> <span class=\"p\">=<\/span> <span class=\"n\">_entityRepository<\/span><span class=\"p\">.<\/span><span class=\"nf\">GetOnlineUserByUsername<\/span><span class=\"p\">(<\/span><span class=\"n\">username<\/span><span class=\"p\">);<\/span>\n  <span class=\"kt\">string<\/span> <span class=\"n\">nsId<\/span> <span class=\"p\">=<\/span> <span class=\"n\">user<\/span><span class=\"p\">.<\/span><span class=\"n\">Group<\/span><span class=\"p\">.<\/span><span class=\"n\">NetSuiteInternalId<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>One of the nicer features of PVS-Studio is that it can identify cases like this, where a null pointer exception is possible.\nBy identifying these and dealing with them you can eliminate an common class of error and deal with it more gracefully.<\/p>\n\n<h4 id=\"expression-resultsucces-is-always-true\">Expression \u2018result.Succes\u2019 is always true<\/h4>\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>\n<span class=\"k\">if<\/span><span class=\"p\">(!<\/span><span class=\"n\">result<\/span><span class=\"p\">.<\/span><span class=\"n\">Success<\/span><span class=\"p\">)<\/span>\n  <span class=\"k\">return<\/span> <span class=\"nf\">Json<\/span><span class=\"p\">(<\/span><span class=\"n\">result<\/span><span class=\"p\">);<\/span>\n\n<span class=\"c1\">\/\/...<\/span>\n\n<span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"n\">result<\/span><span class=\"p\">.<\/span><span class=\"n\">Success<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">{<\/span>    \n    <span class=\"c1\">\/\/...    <\/span>\n\n<span class=\"p\">}<\/span>           \n<\/code><\/pre><\/div><\/div>\n<p>This and a couple other similar examples were identified. This error could imply a serious logic error in the code. At the very least it\nidentifies unecessary checks cluttering up the code and slowing down execution.<\/p>\n\n<h4 id=\"it-is-odd-that-the-body-of-canreadtype-function-is-fully-equivalent-to-the-body-of-canwritetype-function\">It is odd that the body of \u2018CanReadType\u2019 function is fully equivalent to the body of \u2018CanWriteType\u2019 function<\/h4>\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">public<\/span> <span class=\"k\">override<\/span> <span class=\"kt\">bool<\/span> <span class=\"nf\">CanReadType<\/span><span class=\"p\">(<\/span><span class=\"n\">Type<\/span> <span class=\"n\">type<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">return<\/span> <span class=\"nf\">SupportedType<\/span><span class=\"p\">(<\/span><span class=\"n\">type<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"k\">public<\/span> <span class=\"k\">override<\/span> <span class=\"kt\">bool<\/span> <span class=\"nf\">CanWriteType<\/span><span class=\"p\">(<\/span><span class=\"n\">Type<\/span> <span class=\"n\">type<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">return<\/span> <span class=\"nf\">SupportedType<\/span><span class=\"p\">(<\/span><span class=\"n\">type<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>This turned out to be correct for us, since we needed to override both methods.  This class of message can sometimes identify code\nthat can be cominbed to shrink your code base down, or may identify a copy-paste error.<\/p>\n\n<h4 id=\"an-odd-precise-comparison-transactiontaxrate--0-consider-using-a-comparison-with-a-defined-precision-mathabsa-b--epsilon\">An odd precise comparison: transaction.TaxRate == 0. Consider using a comparison with a defined precision: Math.Abs(A-B) &lt; Epsilon<\/h4>\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code> <span class=\"k\">if<\/span><span class=\"p\">(<\/span><span class=\"n\">transaction<\/span><span class=\"p\">.<\/span><span class=\"n\">TaxRate<\/span> <span class=\"p\">==<\/span> <span class=\"m\">0<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>Any instances of comparing floating point values to exact values will be indentified as a low-risk problem.<\/p>\n\n<h4 id=\"a-part-of-conditional-expression-is-always-true-if-it-is-evaluated-billingaddresssameasshipping--on\">A part of conditional expression is always true if it is evaluated: billingAddressSameAsShipping != \u201con\u201d<\/h4>\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"kt\">string<\/span><span class=\"p\">.<\/span><span class=\"nf\">IsNullOrEmpty<\/span><span class=\"p\">(<\/span><span class=\"n\">CFM<\/span><span class=\"p\">.<\/span><span class=\"n\">BillingAddress<\/span><span class=\"p\">.<\/span><span class=\"n\">Id<\/span><span class=\"p\">)<\/span> <span class=\"p\">&amp;&amp;<\/span> \n    <span class=\"kt\">string<\/span><span class=\"p\">.<\/span><span class=\"nf\">IsNullOrEmpty<\/span><span class=\"p\">(<\/span><span class=\"n\">billingAddressSameAsShipping<\/span><span class=\"p\">)<\/span> <span class=\"p\">&amp;&amp;<\/span> \n    <span class=\"n\">billingAddressSameAsShipping<\/span> <span class=\"p\">!=<\/span> <span class=\"s\">\"on\"<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>Another common mistake, this can often arise when an if statement is modified with an extra check later.  In this case, the check for != \u201con\u201d is now unecessary. But\nthis could expose logic mistakes as well.<\/p>\n\n<h4 id=\"the-url-variable-is-assigned-to-itself\">The \u2018url\u2019 variable is assigned to itself<\/h4>\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">url<\/span> <span class=\"p\">=<\/span> <span class=\"n\">url<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"user\/\"<\/span> <span class=\"p\">+<\/span> <span class=\"n\">userId<\/span> <span class=\"p\">+<\/span> <span class=\"s\">\"\/attorney\/\"<\/span> <span class=\"p\">+<\/span> <span class=\"n\">id<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>A copy\/paste error, that likely gets compiled away, but is cluttering up the code still.<\/p>\n\n<h4 id=\"idisposable-object-servererror-is-not-disposed-before-method-returns\">IDisposable object \u2018serverError\u2019 is not disposed before method returns<\/h4>\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kt\">var<\/span> <span class=\"n\">serverError<\/span> <span class=\"p\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nf\">HttpResponseMessage<\/span><span class=\"p\">(<\/span><span class=\"n\">HttpStatusCode<\/span><span class=\"p\">.<\/span><span class=\"n\">InternalServerError<\/span><span class=\"p\">);<\/span>\n<span class=\"k\">return<\/span> <span class=\"n\">Request<\/span><span class=\"p\">.<\/span><span class=\"nf\">CreateResponse<\/span><span class=\"p\">(<\/span><span class=\"n\">HttpStatusCode<\/span><span class=\"p\">.<\/span><span class=\"n\">InternalServerError<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>PVS will identify a few different problems with the IDisposable interface, including this, classes that implement the Dispose method but not the IDisposable interface,\nand classes which have IDisposable memebers but don\u2019t implement IDisposable themselves. Proper handling of these issues can reduce memory use and GC pressure.<\/p>\n\n<h4 id=\"the-datetime-constructor-could-receive-the-0-value-while-positive-value-is-expected-inspect-the-first-argument\">The \u2018DateTime\u2019 constructor could receive the \u20180\u2019 value while positive value is expected. Inspect the first argument<\/h4>\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">DateTime<\/span> <span class=\"n\">now<\/span> <span class=\"p\">=<\/span> <span class=\"n\">DateTime<\/span><span class=\"p\">.<\/span><span class=\"n\">Now<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"n\">year<\/span> <span class=\"p\">&lt;<\/span> <span class=\"m\">0<\/span> <span class=\"p\">||<\/span> <span class=\"n\">year<\/span> <span class=\"p\">&gt;<\/span> <span class=\"n\">now<\/span><span class=\"p\">.<\/span><span class=\"n\">Year<\/span> <span class=\"p\">||<\/span> <span class=\"n\">month<\/span> <span class=\"p\">&lt;=<\/span> <span class=\"m\">0<\/span> <span class=\"p\">||<\/span> <span class=\"n\">month<\/span> <span class=\"p\">&gt;<\/span> <span class=\"m\">12<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">throw<\/span> <span class=\"k\">new<\/span> <span class=\"nf\">Exception<\/span><span class=\"p\">(<\/span><span class=\"s\">\"The input query time is not valid\"<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"n\">DateTime<\/span> <span class=\"n\">StartOfMonth<\/span> <span class=\"p\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nf\">DateTime<\/span><span class=\"p\">(<\/span><span class=\"n\">year<\/span><span class=\"p\">,<\/span> <span class=\"n\">month<\/span><span class=\"p\">,<\/span> <span class=\"m\">1<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>PVS Studio has identified that our check for \u201cyear &lt; 0\u201d is not sufficient to gaurantee correct input to the DateTime constructor.  It should be year &lt;= 0.<\/p>\n\n<h4 id=\"the-dateneeded-variable-is-assigned-values-twice-successively-perhaps-this-is-a-mistake\">The \u2018DateNeeded\u2019 variable is assigned values twice successively. Perhaps this is a mistake<\/h4>\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"n\">detail<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">while<\/span> <span class=\"p\">((<\/span><span class=\"n\">date<\/span><span class=\"p\">.<\/span><span class=\"nf\">ToString<\/span><span class=\"p\">(<\/span><span class=\"s\">\"ddd\"<\/span><span class=\"p\">)<\/span> <span class=\"p\">!=<\/span> <span class=\"n\">day<\/span><span class=\"p\">))<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"n\">date<\/span> <span class=\"p\">=<\/span> <span class=\"n\">date<\/span><span class=\"p\">.<\/span><span class=\"nf\">AddDays<\/span><span class=\"p\">(<\/span><span class=\"m\">1<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"c1\">\/\/if the date is a holiday, add 1 <\/span>\n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"n\">santa<\/span><span class=\"p\">.<\/span><span class=\"nf\">CheckDate<\/span><span class=\"p\">(<\/span><span class=\"n\">DateNeeded<\/span><span class=\"p\">,<\/span> <span class=\"n\">type<\/span><span class=\"p\">))<\/span>\n        <span class=\"n\">DateNeeded<\/span> <span class=\"p\">=<\/span> <span class=\"n\">date<\/span><span class=\"p\">.<\/span><span class=\"nf\">AddDays<\/span><span class=\"p\">(<\/span><span class=\"m\">1<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"c1\">\/\/fixes time <\/span>\n<span class=\"n\">date<\/span> <span class=\"p\">=<\/span> <span class=\"n\">date<\/span><span class=\"p\">.<\/span><span class=\"nf\">AddHours<\/span><span class=\"p\">(<\/span><span class=\"n\">time<\/span> <span class=\"p\">-<\/span> <span class=\"n\">date<\/span><span class=\"p\">.<\/span><span class=\"n\">Hour<\/span><span class=\"p\">);<\/span>\n<span class=\"n\">date<\/span> <span class=\"p\">=<\/span> <span class=\"n\">date<\/span><span class=\"p\">.<\/span><span class=\"nf\">AddMinutes<\/span><span class=\"p\">(-<\/span><span class=\"n\">date<\/span><span class=\"p\">.<\/span><span class=\"n\">Minute<\/span><span class=\"p\">);<\/span>\n\n<span class=\"n\">DateNeeded<\/span> <span class=\"p\">=<\/span> <span class=\"n\">date<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>PVS Studio has identified that the assignment of DateNeeded = date.AddDays(1) is nonsensical, because it is immediately overritten before being used.<\/p>\n\n<h4 id=\"the-return-value-of-function-insert-is-required-to-be-utilized\">The return value of function \u2018Insert\u2019 is required to be utilized.<\/h4>\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">userString<\/span><span class=\"p\">.<\/span><span class=\"nf\">Insert<\/span><span class=\"p\">(<\/span><span class=\"m\">0<\/span><span class=\"p\">,<\/span> <span class=\"n\">suffixStr<\/span><span class=\"p\">);<\/span>\n   \n<\/code><\/pre><\/div><\/div>\n<p>This is a very common mistake. C# strings are immutable, and so the pattern for functions like insert, substring, etc is to return the new string.\nYou can easily forget this, and the operation you were trying to do on the string just doesn\u2019t happen at all.<\/p>\n\n<h2 id=\"quick-review\">Quick Review<\/h2>\n\n<p>This doesn\u2019t represent all of the C# capabilities that PVS-Studio has, these are just the issues it found in our project. It integrates nicely with Visual Studio (see screenshot below),\nbut you can use it standalone as well.  They have a nice evaluation version that let\u2019s you try it out for quite a long time.  I find the errors it finds to be much more relevant\nthan Resharper\u2019s analyses, which are numerous but seem to mostly be stylistic.  There do not appear to be any optimization tips for C# yet, as there are for C++ code, but perhaps\nthat is coming in the future.<\/p>\n\n<p><img src=\"\/images\/pvs.png\" alt=\"pvs\" title=\"PVS Visual Studio\" \/><\/p>\n","pubDate":"Tue, 01 Nov 2016 19:17:27 +0000","link":"https:\/\/jackmott.github.io\/\/programming\/2016\/11\/01\/PVS-Studio.html","guid":"https:\/\/jackmott.github.io\/\/programming\/2016\/11\/01\/PVS-Studio.html","category":"programming"},{"title":"Language Helper","description":"<p>One of my many half finished side projects is a <a href=\"http:\/\/jackmott.github.io\/dungeonbuilder\/\">text adventure engine<\/a>, where players can play Zork-like games,\nor make their own game from within the engine as well.  One of the tricky problems I ran into was being able to handle certain english grammer issues\nin the engine, in a way that was not extremely annoying for users.  For instance, you might want to indicate in the engine editor that a room has 2 gold coins and a dagger\nin it. When someone plays the game you could do the usual gamedev thing and present the room something like this:<\/p>\n\n<div class=\"highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>You enter a scary dungeon.  \nYou see:\n  2 gold coins\n  1 dagger\n\n&gt; Take 1 coin\nYou take 1 coin.\nYou see:\n  1 gold coin\n  1 dagger\n<\/code><\/pre><\/div><\/div>\n\n<p>It is easy to write code to do that, but it breaks the fourth wall, and no longer reads like a story.  What if instead you wanted it to look like so:<\/p>\n\n<div class=\"highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>You enter a scary dungeon.  There are two gold coins and a dagger here.\n&gt; Take 1 coin\nYou take a coin, and now a gold coin and a dagger remain\n<\/code><\/pre><\/div><\/div>\n\n<p>This is harder code to write, especially when you support a editor where users might enter any words they want as items.  You have to identify if the indefinite article\nfor a given word should be \u201ca\u201d or \u201can\u201d for starters, which has no simple rules you can follow.  You need to know the plural forms of words, \nwhich is not as simple as just adding an s.<\/p>\n\n<h2 id=\"the-languagehelper-library\">The LanguageHelper library<\/h2>\n\n<p>I\u2019ve put together a library that helps make some of these things easier, and might be useful for various text-based RPG applications. Maybe even useful for non text based ones\nnow that text to speech is starting to sound convincing.<\/p>\n\n<p>What I have so far:<\/p>\n\n<ul>\n  <li>Query any word for it\u2019s plural form<\/li>\n  <li>Query any word for the correct indefinite article<\/li>\n  <li>Query any verb for past tense, progressive tense, and past perfect tense<\/li>\n  <li>Turn an integer into the words that represent the integer<\/li>\n  <li>A json dictionary format so you can easily add your own words, or cull the dictionary for performance\/size reasons<\/li>\n<\/ul>\n\n<p>Things I would like to add:<\/p>\n\n<ul>\n  <li>Query a word for synonyms and antonyms<\/li>\n  <li>More complete coverage of verb conjugation<\/li>\n  <li>Pronunciation data?<\/li>\n  <li>More languages?<\/li>\n<\/ul>\n\n<p>The library is currently in .NET 2.0, so it can be consumed by any C# or F# code, including <a href=\"https:\/\/unity3d.com\/\">Unity3D<\/a>, but if people think this sounds useful \nI would create a C++ version as well.<\/p>\n\n<h2 id=\"useful\">Useful?<\/h2>\n\n<p>Does this sound useful? Does this already exist? What other features would you need? Let me know!<\/p>\n\n<h2 id=\"sample-use-case\">Sample Use Case<\/h2>\n\n<p>Following is a simple use case example.  Notice there are some subtleties that the library handles well. \u201csteel ingot\u201d is a two word item.  The library\ncorrect pulls out the indefinitely article for the leading word \u201csteel\u201d but applies the plural form only to the trailing word.<\/p>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>\n    <span class=\"c\">(* Some imaginary blacksmith entity structure *)<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">item<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"steel ingot\"<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">qty<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">2<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">currentAction<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"forge\"<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">pastAction<\/span>  <span class=\"o\">=<\/span> <span class=\"s2\">\"sleep\"<\/span>\n\n    <span class=\"c\">(* Player asks what the Smith has for sale *)<\/span> \n    <span class=\"k\">let<\/span> <span class=\"n\">response<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"I have \"<\/span> <span class=\"o\">+<\/span> <span class=\"n\">wordBank<\/span><span class=\"o\">.<\/span><span class=\"nc\">QueryNounQty<\/span><span class=\"p\">(<\/span><span class=\"n\">item<\/span><span class=\"o\">,<\/span><span class=\"n\">qty<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">printf<\/span> <span class=\"s2\">\"%A<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">\"<\/span> <span class=\"n\">response<\/span>\n    <span class=\"c\">(* Output: I have two steel ingots *)<\/span>\n\n    <span class=\"c\">(* Smith only has 1 *)<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">qty<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">1<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">response<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"I have \"<\/span> <span class=\"o\">+<\/span> <span class=\"n\">wordBank<\/span><span class=\"o\">.<\/span><span class=\"nc\">QueryNounQty<\/span><span class=\"p\">(<\/span><span class=\"n\">item<\/span><span class=\"o\">,<\/span><span class=\"n\">qty<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">printf<\/span> <span class=\"s2\">\"%A<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">\"<\/span> <span class=\"n\">response<\/span>\n    <span class=\"c\">(* Output: I have a steel ingot *)<\/span>\n\n    <span class=\"c\">(* Smith has none left *)<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">qty<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>                \n    <span class=\"k\">let<\/span> <span class=\"n\">response<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"I have \"<\/span> <span class=\"o\">+<\/span> <span class=\"n\">wordBank<\/span><span class=\"o\">.<\/span><span class=\"nc\">QueryNounQty<\/span><span class=\"p\">(<\/span><span class=\"n\">item<\/span><span class=\"o\">,<\/span><span class=\"n\">qty<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">printf<\/span> <span class=\"s2\">\"%A<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">\"<\/span> <span class=\"n\">response<\/span>\n    <span class=\"c\">(* Output: I have no steel ingots *)<\/span>\n\n    <span class=\"c\">(* What are you doing? *)<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">response<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"I am \"<\/span> <span class=\"o\">+<\/span> <span class=\"n\">wordBank<\/span><span class=\"o\">.<\/span><span class=\"nc\">QueryVerbPresent<\/span><span class=\"p\">(<\/span><span class=\"n\">currentAction<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">printf<\/span> <span class=\"s2\">\"%A<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">\"<\/span> <span class=\"n\">response<\/span>\n    <span class=\"c\">(* Output: I am forging *)<\/span>\n\n    <span class=\"c\">(* What did you do earlier? *)<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">response<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"I  \"<\/span> <span class=\"o\">+<\/span> <span class=\"n\">wordBank<\/span><span class=\"o\">.<\/span><span class=\"nc\">QueryVerbPast<\/span><span class=\"p\">(<\/span><span class=\"n\">pastAction<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">printf<\/span> <span class=\"s2\">\"%A<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">\"<\/span> <span class=\"n\">response<\/span>\n    <span class=\"c\">(* Output: I slept *)<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h2 id=\"some-sample-queries\">Some sample queries<\/h2>\n\n<p><img src=\"\/images\/demo.gif\" alt=\"DemoGif\" title=\"Demo Gif\" \/><\/p>\n\n","pubDate":"Thu, 29 Sep 2016 19:17:27 +0000","link":"https:\/\/jackmott.github.io\/\/programming\/2016\/09\/29\/language-helper.html","guid":"https:\/\/jackmott.github.io\/\/programming\/2016\/09\/29\/language-helper.html","category":"programming"},{"title":"Taking out the garbage","description":"<p>One of the never ending arguments about languages is the pros and cons of garbage collection. Some people hate it because they think it is slow,\nothers insist it is fast, some hate that it takes away control from them, others love it for that same reason. I\u2019m going to explore this a bit \nand show some pros and cons that arise, and how you can deal with them in C#, Java, and C++.  I will be creating basic framework for a game \nin the style of <a href=\"https:\/\/minecraft.net\/en\/\">Minecraft<\/a>. Don\u2019t get too excited, there won\u2019t be any rendering or anything playable. Also, please\ndon\u2019t take any of these experiments to represent evidence of innate performance qualities of any of these languages. In all three cases, I am\naware of ways to optimize the code further, this is just meant to illustrate the relative costs of allocation and how you can start\nreducing those costs in each language. If I get emails about fairness I\u2019m going to refer you to this paragraph.<\/p>\n\n<h2 id=\"the-naive-approach-in-c-sharp\">The Naive Approach, in C Sharp<\/h2>\n\n<p><a href=\"https:\/\/gist.github.com\/jackmott\/6d0ba936b24595402b49b6e76137c788\">Link To Gist<\/a><\/p>\n\n<p>Above is a link to how many developers might naively being to implement a game like Minecraft. (note, that experienced AAA game devs, their eyes would \nbleed at this) It is 3d, so of course you have the obligatory Vector class, with obligatory operator overloading so you can do simple \noperations on those vectors with very obvious code and very little typing. The game world consists of Chunks, that are loaded as you\napproach close enough to them, and unloaded as you get too far away. Each Chunk has a number of Entities, that move around at various speeds each game tick. \nThe player moves forward and every few ticks she passes into a new Chunk, which causes 1 Chunk to be\nloaded and another to be unloaded. Each Chunk also has a number of Blocks.  Everything in the game, Chunks, Blocks, Entities have positions\nrepresented by a Vector class. Each tick of the game, as the player moves forward a little bit, the chunks are iterated over and told to\nupdate their entities, then checked to see if they have gone out of range, and removed if so.  If a chunk is removed, a new one is added to\nreplace it.<\/p>\n\n<p>Simple enough, and the approach above would and does work fine for many games. It isn\u2019t completely dumb, it uses an\narray backed List to keep track of things, because arrays are fast, and it pre-allocates them to the proper size when it can to avoid \nwasting memory and cpu on growing the array. Modern computers are fast, so this shouldn\u2019t be a problem!<\/p>\n\n<p>But the problem is that while computers are fast, so too have our expectations grown.  A screen used to have 64,000 pixels max, now they\nhave 2 million at a minimum. A game world that you could explore for hours used to be impressive, but now players expect endless worlds\nlarger than planets, with detail down to blades of grass. And all of that has to happen at 90FPS on two monitors at once because VR! So, while our game \nis simple in principle, we load up and move around a <em>lot<\/em> of simple things. 65k blocks per chunk, 100 chunks at time, plus 1,000 entities \nper chunk all moving around every game tick.<\/p>\n\n<h3 id=\"naive-approach\">Naive Approach<\/h3>\n\n<p>You can see in the code we have a rudimentary frame rate lock, at 60fps, and on a modern Core I7 cpu we aren\u2019t hitting that frame rate ever! \nSome other troubling stats (collected with Perfmon) are clear:<\/p>\n\n<ul>\n  <li>80% of CPU time spent in garbage collection!!!<\/li>\n  <li>600 MB\/s allocations<\/li>\n  <li>5.8 seconds to load the world.<\/li>\n  <li>31.4 ms per tick<\/li>\n<\/ul>\n\n<p>I\u2019m not even rendering yet! Or playing sounds, or doing networking. This is the kind of performance that causes people to say \u201cGarbage collection is terrible\nand slow!\u201d, which causes people to respond \u201cNo you just aren\u2019t using it right!\u201d, which then leads to \u201cIf I have to think about memory management anyway, what \nis the point of garbage collection!\u201d and so on.<\/p>\n\n<p>The root problem here, as is often the case, is too many allocations, which would be a problem even if there wasn\u2019t any garbage collector, though perhaps\nnot quite as bad.  I am casually creating new Vectors all the time for just a short while and then tossing them away. With blocks I am creating longer \nlived objects and then regularly tossing them to the garbage collector as well.  There are many things I can do to improve this, but C# has one feature\nwhich is an \u2018easy fix\u2019, and that is structs, which are a value type.  They are not allocated on the heap, and they are passed by value.  You can\u2019t\njust turn all of your classes into structs, as larger classes being copied around by value would be wasteful, but small ones you can.  In this case, \nVector is a perfect candidate, at only 12 bytes.<\/p>\n\n<h3 id=\"change-class-vector-to-struct-vector\">Change class Vector to struct Vector<\/h3>\n\n<p>Just six characters and look at the difference:<\/p>\n\n<ul>\n  <li>45% of CPU time spent in garbage collection<\/li>\n  <li>200 MB\/s allocations<\/li>\n  <li>4.4 seconds to load the world.<\/li>\n  <li>4.1ms per tick<\/li>\n<\/ul>\n\n<p>Suddenly things have gone from a hopeless situation where there is negative time for the frame rate budget for rendering, to having \n11 milliseconds and 50% of the CPU to spare. But the struct is just a partial fix.  Next I will refactor the code a bit for even better performance.<\/p>\n\n<h3 id=\"refactor\">Refactor<\/h3>\n\n<p><a href=\"https:\/\/gist.github.com\/jackmott\/fa4ca37bd372c1fe99f514bcf92519a0\">Link to Gist<\/a><\/p>\n\n<p>After a more serious refactoring:<\/p>\n\n<ul>\n  <li>0.1% of CPU time spent in garbage collection<\/li>\n  <li>1 MB\/s allocations<\/li>\n  <li>25ms to load the world<\/li>\n  <li>0.97ms per tick<\/li>\n<\/ul>\n\n<p>A huge difference! Very little time is spent on GC now, world load times are now instant and game ticks now process in under a millisecond.  At this\npoint almost nothing happens in a game tic except updating positions of entities, and occasional unloading of one chunk to be replaced by another.<\/p>\n\n<h3 id=\"what-changed\">What Changed?<\/h3>\n\n<p>Lots of little things, using arrays instead of List when it doesn\u2019t cause any extra work saves a tiny bit of overhead.  Benefitting from\nsome array bounds elisions by structuring loops just right in some places.  Reducing GC pressure and improving runtime by not using <em>foreach<\/em> on Lists, and\nother minor tweaks. But the main thing, was rethinking how the data is organized.  Previously, each chunk had 65k Block objects.  By thinking about the data,\none can figure out how many possible block types there are.  They will likely have some bound. In this case 256 was chosen to replicate Minecraft. You could \neasily bump that up to a short or int and still realize the bulk of this improvement. So instead of each chunk allocating and storing a complete Block\nobject 65k times, it just stores an index into a global array of Blocks. This is similar to how Minecraft actually does things.  This optimization\nonly makes sense if blocks are static things, most of the time, as they are in Minecraft.  You can break blocks, and place blocks, but they rarely\nhave state associated with them that changes.  This trick will not work with entities as currently designed, as they are moving around, their health is changing,\nand so on.<\/p>\n\n<p>This sort of thing is a very basic example of <a href=\"https:\/\/dataorientedprogramming.wordpress.com\/tag\/mike-acton\/\">Data Oriented Programming<\/a>. Think a little\nbit more about what is actually happening with your data in memory, and less about what an idiomatic OOP design should be. Note that had you proceeded with \nthe original design further into the development cycle, refactoring to make these changes could end up very very painful. Now that memory isn\u2019t being shuffled around \nlike mad, there is plenty of CPU available to replace the mockup code with some real \u2018AI\u2019.<\/p>\n\n<p>One could go further with this, for instance pulling the Vector class out and replacing it with an array of positions, or even separate arrays of\nx,y,and z values, depending on how the data is accessed could have big speed benefits due to cache locality and allow you to utilize SIMD instructions.  But that sort of madness is beyond the scope\nof this blog post.<\/p>\n\n<h2 id=\"the-naive-approach-java\">The Naive Approach, Java<\/h2>\n\n<p><a href=\"https:\/\/gist.github.com\/jackmott\/ddc406ecaf1cd9b86bb5a3dc2581cf28\">Link to Gist<\/a><\/p>\n\n<p>Recreating the same naive program in Java, I get the following stats (collected with Mission Control):<\/p>\n\n<ul>\n  <li>17% of CPU time spent in garbage collection<\/li>\n  <li>156 MB\/s allocations<\/li>\n  <li>4.1s to load the world<\/li>\n  <li>4.9ms per tick<\/li>\n<\/ul>\n\n<p>Java has no value types yet, so we can\u2019t apply the trick of making Vector a struct, but the memory use and GC time is already much better\nthan the .NET case where we made Vector a struct.  Part of the reason for this is that the JVM does escape analysis, so some of the wasteful\nVector allocations that are only being used within a function can be allocated on the stack automatically. Interestingly, escape analysis is\na feature coming soon to .NET, and value types are coming soon to Java.<\/p>\n\n<h3 id=\"java-refactored\">Java refactored<\/h3>\n\n<p><a href=\"https:\/\/gist.github.com\/jackmott\/21d8765608767f972b0f8b69a344d4cf\">Link to Gist<\/a><\/p>\n\n<p>But what if I refactor to avoid the wasteful allocations in the first place?<\/p>\n\n<ul>\n  <li>.04% of CPU time spent in garbage collection<\/li>\n  <li>1.3 MB\/s allocations<\/li>\n  <li>50ms to load the world<\/li>\n  <li>1.18ms per tick<\/li>\n<\/ul>\n\n<p>The stats are now very much inline with the refactored .NET code.  While slightly worse, don\u2019t read too much into that, I\u2019m not as experienced\nat Java and probably have more obvious small mistakes. What should be noted here, is that avoiding wasteful allocations is important, no matter\nthe platform. One obvious way to further improve the Java code would be to eliminate the Vector class entirely, and just use float x,y,z in place\nevery where we use it.  This is a bit painful, but gets rid of the reliance on escape analysis and saves some object overhead. This would\nbe equivalent to converting the class to a value type, if\/when Java has those. Another option is to use a pool of Vector objects, which you reuse.<\/p>\n\n<h2 id=\"c-extremely-naively\">C++ Extremely naively<\/h2>\n\n<p>The first experiment I ran with C++ was to strictly copy the behavior of C# \/ Java, and create the same objects, on the heap, every time.\nThis was very unnatural, as creating a <em>new Vector<\/em> and then 2 lines of code later calling <em>delete<\/em> on it kind of alerts you to the \nabsurdity of the situation. But for completeness I wrote that code and:<\/p>\n\n<ul>\n  <li>0% of CPU time spent in garbage collection (but lots spent allocating!)<\/li>\n  <li>1 second to load the world<\/li>\n  <li>17.39ms per tick<\/li>\n<\/ul>\n\n<p>While the game world loads a lot faster, the per tick performance is still really bad. Even worse than the naive\nJava implementation, probably because there is no escape analysis saving us from allocating Vectors all over the place. This code is \nactually kind of absurdly naive though, it takes extra typing annoyance to make code this bad and it is pretty unlikely even \nsomeone not keen on performance would do this.  However this is how I was taught to do things with C++ in school, so you never\nknow.<\/p>\n\n<h3 id=\"minor-refactor---no-more-heap-allocating-vectors\">Minor refactor - no more heap allocating Vectors<\/h3>\n\n<p><a href=\"https:\/\/gist.github.com\/jackmott\/a14abc480429a0aa494275b8e30e3511\">Link To Gist<\/a><\/p>\n\n<p>This is vaguely equivalent to making the Vector class a struct in C#.  I\u2019m also passing Vector by value, and never allocating it on the heap. The\ncode gets smaller and simpler, I don\u2019t have to worry about memory management as much.<\/p>\n\n<ul>\n  <li>0% of CPU time spent in garbage collection (but some spent allocating)<\/li>\n  <li>737ms to load the world<\/li>\n  <li>1.4ms per tick<\/li>\n<\/ul>\n\n<h3 id=\"major-refactor\">Major refactor<\/h3>\n\n<p><a href=\"https:\/\/gist.github.com\/jackmott\/f2fb4d967003f0ca18494ca2cb1e8fe0\">Link To Gist<\/a><\/p>\n\n<p><em>C++ implementation improvements courtesy of <a href=\"https:\/\/gist.github.com\/jcelerier\">Jean-Micha\u00ebl Celerier<\/a><\/em><\/p>\n\n<p>Applying the same tricks as we did in the other languages,  so that we aren\u2019t allocating so many blocks, and a few other tricks that C++\ngives us the flexibility to do:<\/p>\n\n<ul>\n  <li>0% of CPU time spent in garbage collection (a bit spent allocating)<\/li>\n  <li>8ms to load the world<\/li>\n  <li>0.55ms per tick<\/li>\n<\/ul>\n\n<h2 id=\"rust-naively\">Rust naively<\/h2>\n\n<p><a href=\"https:\/\/gist.github.com\/jackmott\/7a235472d74f9a2bbcfc1d6cae5ad7f4\">Link To Gist<\/a><\/p>\n\n<p><em>This implementation contributed kindly by <a href=\"https:\/\/github.com\/Maplicant\">Maplicant<\/a><\/em><\/p>\n\n<p>This was implemented by a newcomer to Rust who attempted a translation of the Naive C# implementation, performance is quite good! fastest\nof all the naive ones.<\/p>\n\n<ul>\n  <li>0% of CPU time spent in garbage collection (but lots spent allocating!)<\/li>\n  <li>1.2 seconds to load the world<\/li>\n  <li>1.7ms per tick<\/li>\n<\/ul>\n\n<h2 id=\"rust-refactored\">Rust Refactored<\/h2>\n\n<p><a href=\"https:\/\/gist.github.com\/jackmott\/c6a37ba67b82efdd7da08c43ef271a48\">Link To Gist<\/a><\/p>\n\n<p><em>This implementation contributed kindly by <a href=\"https:\/\/github.com\/Dr-Emann\">Zachary Dremann<\/a><\/em><\/p>\n\n<p>The refactored Rust implementation also performs very well:<\/p>\n\n<ul>\n  <li>0% of CPU time spent in garbage collection (but some spent allocating!)<\/li>\n  <li>14 milliseconds to load the world<\/li>\n  <li>0.7ms per tick<\/li>\n<\/ul>\n\n<h2 id=\"go-haskell\">Go? Haskell?<\/h2>\n\n<p>The <a href=\"https:\/\/www.reddit.com\/r\/haskell\/comments\/52j2c9\/performance_in_the_large_benchmark\/\">Haskell<\/a> and <a href=\"https:\/\/gist.github.com\/dgryski\/61763e2ee58d3446b25bbe00b44f974e\">Go<\/a> \ncommunities have gotten into the act too with lots of fun experiments. I won\u2019t be able to collate the performance of all of these efforts but they are fun to read up on.<\/p>\n\n<h2 id=\"performance-comparisons\">Performance Comparisons:<\/h2>\n\n<p>A couple of quick graphs showing some performance comparisons. Again, I reiterate not to read these as proof of the performance superiority of any memory \nmanagement approach. I assure you that all of these implementations could optimized further than they are here.  The point is to show how allocations are expensive \nin all cases, but in different ways, and how good design brings performance into reasonable ranges in all cases, though with differing levels of effort.<\/p>\n\n<h3 id=\"the-naive-approaches-with-vector-fixes-in-c-and-c\">The Naive Approaches (With Vector Fixes in C# and C++)<\/h3>\n\n<p><img src=\"\/images\/mem-slow.png\" alt=\"Naive\" title=\"Naive\" \/><\/p>\n\n<p>Note the Y Axis here is Log Time. Notice how in all 4 languages performance starts to degrade at the same time, about 1,000 ticks in, probably reflecting when the heap begins to fill up,\nand allocations get expensive for C++, and GC has to kick in more for .NET and Java. While one could bicker about which language is doing best here for eternity,\nthe fact is all three implementations are completely unacceptable.<\/p>\n\n<h3 id=\"the-refactored-approaches\">The Refactored Approaches<\/h3>\n\n<p><img src=\"\/images\/mem-fast.png\" alt=\"Faster\" title=\"Faster\" \/><\/p>\n\n<p>Notice all 4 languages perform well here, but the garbage collected languages do still have GC pauses, which are a big problem in gaming.  Most game\ndevelopers would get even more clever, using object pooling and other techniques to try to get allocations down to zero within the main game loop, if possible.<\/p>\n\n<h2 id=\"conclusions\">Conclusions<\/h2>\n\n<p>The main take away here is think about how you work with memory, no matter what language you use.  C# offers some nice tools in value types to make\nthis a bit easier.  Java on the other hand uses escape analysis to attempt to \u201cauto struct\u201d things for you. Both of these approaches have pros and cons.\nIt is less important to worry about which is best, and more important just to understand how your language works, so the code you type will leverage\nit\u2019s strengths, and avoid it\u2019s weaknesses.  C++ doesn\u2019t make allocation free, allocating too much is one of the primary causes of performance\nproblems in C++ code as well.  It does give you the most control to make things perform well, but it will be up to you to figure it out.\nManage your memory well.<\/p>\n\n<h2 id=\"benchmark-details\">Benchmark Details<\/h2>\n\n<p>All benchmarks run with what I believe to be the latest and greatest compilers available for Windows for each language (Debateable for C++). \nIf you identify cases where code or compiler\/environment choices are sub optimal, email me please.<\/p>\n\n<h4 id=\"environment\">Environment<\/h4>\n<div class=\"language-ini highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"err\">Host<\/span> <span class=\"err\">Process<\/span> <span class=\"err\">Environment<\/span> <span class=\"err\">Information:<\/span>\n<span class=\"py\">BenchmarkDotNet<\/span><span class=\"p\">=<\/span><span class=\"s\">v0.9.8.0<\/span>\n<span class=\"py\">OS<\/span><span class=\"p\">=<\/span><span class=\"s\">Microsoft Windows NT 6.2.9200.0<\/span>\n<span class=\"py\">Processor<\/span><span class=\"p\">=<\/span><span class=\"s\">Intel(R) Core(TM) i7-4712HQ CPU 2.30GHz, ProcessorCount=8<\/span>\n<span class=\"py\">Frequency<\/span><span class=\"p\">=<\/span><span class=\"s\">2240907 ticks, Resolution=446.2479 ns, Timer=TSC<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h4 id=\"c-runtime-details\">C# Runtime Details<\/h4>\n<div class=\"language-ini highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"py\">CLR<\/span><span class=\"p\">=<\/span><span class=\"s\">MS.NET 4.0.30319.42000, Arch=64-bit RELEASE [RyuJIT]<\/span>\n<span class=\"py\">GC<\/span><span class=\"p\">=<\/span><span class=\"s\">Concurrent Workstation<\/span>\n<span class=\"py\">JitModules<\/span><span class=\"p\">=<\/span><span class=\"s\">clrjit-v4.6.1590.0  <\/span>\n<span class=\"py\">Jit<\/span><span class=\"p\">=<\/span><span class=\"s\">RyuJit  GarbageCollection=Concurrent Workstation  <\/span>\n\n<\/code><\/pre><\/div><\/div>\n\n<h3 id=\"c-details\">C++ Details<\/h3>\n<p>Visual Studio 2015 Update 3, Optimizations set for maximum speed, AVX2 Instructions on<\/p>\n\n<h3 id=\"java-details\">Java Details<\/h3>\n<p>Oracle Java 64bit version 8 update 102\nTesting done with JMH<\/p>\n\n<h3 id=\"rust-details\">Rust Details<\/h3>\n<p>rustc 1.13.0\nbuild with <code class=\"highlighter-rouge\">cargo rustc --release -- -C lto -C target-cpu=native<\/code><\/p>\n","pubDate":"Thu, 01 Sep 2016 19:17:27 +0000","link":"https:\/\/jackmott.github.io\/\/programming\/2016\/09\/01\/performance-in-the-large.html","guid":"https:\/\/jackmott.github.io\/\/programming\/2016\/09\/01\/performance-in-the-large.html","category":"programming"},{"title":"Think Before You Parallelize","description":"<p>In 2005 Intel release the Pentium D, which began the era of multi-core desktop CPUs.  Today, even our phones have multiple cores. Making use\nof all of those cores it not always easy to do, but modern languages and libraries have come a long way to help programmers take advantage.\nAll kinds of utility functions and concurrent abstraction have been developed in an attempt to make using all our cores more accessible \nand simple. Sometimes these abstractions have a lot of overhead though, and sometimes it doesn\u2019t even make sense to parallelize an operation \nin the first place.<\/p>\n\n<h2 id=\"dont-parallelize-when-it-is-already-parallelized\">Don\u2019t Parallelize when it is already Parallelized<\/h2>\n\n<p>Suppose you are working on a big number crunching function for a high traffic website that is a bit of a performance bottleneck. You get the idea to\nparallelize it and it tests much faster on your dev machine with 4 cores. You expect great things on the 24 core production server. However\nonce you deploy you find that performance in production is actually slightly worse!  What you forgot was that the web server was already parallelizing \nthings at a higher level, using all 24 production cores to handle multiple requests simultaneously.  When your paralellized function\nfires up, all the other cores are busy with other requests.  So you take the hit of whatever overhead was required to parallelize the function\nwith no benefit.<\/p>\n\n<p>On the other hand, if your website was say, a low traffic internal website with only a few dozen hits per day, then the plan to parallelize would\nlikely pay off, as there will always be spare cores to crunch the numbers fast. You have to consider the overall CPU utilization of your webserver,\nand how your parellelized function will interact with the other jobs going on. Will it thrash the L1 cache and slow other things down? Test and\nmeasure.<\/p>\n\n<p>Another scenario, say you are working on 3D game, you have some trick physics math where you need to crunch numbers, maybe adding realistic building\nphysics to Minecraft.  But separate threads are already handling procedural generation of new chunks, rendering, networking, and player input. If\nthese are keeping most of the system\u2019s cores busy, then parallelizing your physics code isn\u2019t going to help overall. On the other hand if those\nother threads are not doing a lot of work, cores may indeed be free for you to crunch some physics.<\/p>\n\n<p>So think about the system your code is running in, if things are getting parallelized at a higher level, it may not do any good to do it\nagain at a lower level. Instead, focus on algorithms that run as efficiently as possible on a single core.<\/p>\n\n<h2 id=\"consider-your-target-hardware\">Consider your target hardware<\/h2>\n\n<p>Many developers have very nice machines, probably with a minimum of 8 logical cores these days, possibly more.  But consider the entire scope\nof where your code might run.  Will it run on a low cost virtualized web app fabric in the cloud?  This may only have 1 or 2 virtual cores for\nyou to work with.  Will it run on old desktops or cheap phones, that maybe only have 2 cores?  An algorithm that gets sped up on your 8 core system\nat home may not fair so well on systems with only 2 or 3.<\/p>\n\n<h2 id=\"case-study-easy-parallel-loops\">Case Study Easy Parallel Loops<\/h2>\n\n<p>It is common in a given programming language to have compiler hints or library functions for doing easy parallel loops when it is appropriate. What happens\nbehind the scenes can be very different depending on the abstractions each language or library uses.  In some cases a number of threads may be created to \noperate on chunks of the loop, or ThreadPools may be used to reduce the overhead of creating Threads. It is important to have a rough understanding of how \nthe abstractions available to you work, so you can make educated guesses about when it might be useful to use them, how to tune them, and how to measure them.\nAt minimum you should consider the following issues.<\/p>\n\n<p>If the computational overhead of creating or managing the thread is greater than the benefit you get, you can end up with a slower results\nthan you would doing a single threaded implementation. I will compare some toy workloads with some common parallel loop abstractions \nin C#, F#, C++ and Java.<\/p>\n\n<h3 id=\"csharp\">CSharp<\/h3>\n\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    \n    <span class=\"k\">public<\/span> <span class=\"kt\">double<\/span> <span class=\"nf\">ImperativeSquareSum<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"kt\">var<\/span> <span class=\"n\">localArray<\/span> <span class=\"p\">=<\/span> <span class=\"n\">rawArray<\/span><span class=\"p\">;<\/span>               \n        <span class=\"kt\">double<\/span> <span class=\"n\">result<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0.0<\/span><span class=\"p\">;<\/span>\n        <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"p\">&lt;<\/span> <span class=\"n\">localArray<\/span><span class=\"p\">.<\/span><span class=\"n\">Length<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span><span class=\"p\">++)<\/span>\n        <span class=\"p\">{<\/span>\n           <span class=\"n\">result<\/span> <span class=\"p\">+=<\/span> <span class=\"c1\">\/\/Do Work<\/span>\n        <span class=\"p\">}<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">result<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n         \n    <span class=\"k\">public<\/span> <span class=\"kt\">double<\/span> <span class=\"nf\">LinqParallelSquareSum<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"kt\">var<\/span> <span class=\"n\">localArray<\/span> <span class=\"p\">=<\/span> <span class=\"n\">rawArray<\/span><span class=\"p\">;<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">localArray<\/span><span class=\"p\">.<\/span><span class=\"nf\">AsParallel<\/span><span class=\"p\">().<\/span><span class=\"nf\">Sum<\/span><span class=\"p\">(<\/span><span class=\"cm\">\/* Do Work *\/<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n    \n    <span class=\"k\">public<\/span> <span class=\"kt\">double<\/span> <span class=\"nf\">ParallelForSquareSum<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"kt\">var<\/span> <span class=\"n\">localArray<\/span> <span class=\"p\">=<\/span> <span class=\"n\">rawArray<\/span><span class=\"p\">;<\/span>\n        <span class=\"kt\">object<\/span> <span class=\"n\">lockObject<\/span> <span class=\"p\">=<\/span> <span class=\"k\">new<\/span> <span class=\"kt\">object<\/span><span class=\"p\">();<\/span>\n        <span class=\"kt\">double<\/span> <span class=\"n\">result<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0.0<\/span><span class=\"p\">;<\/span>\n        <span class=\"n\">Parallel<\/span><span class=\"p\">.<\/span><span class=\"nf\">For<\/span><span class=\"p\">(<\/span><span class=\"m\">0<\/span><span class=\"p\">,<\/span> <span class=\"n\">localArray<\/span><span class=\"p\">.<\/span><span class=\"n\">Length<\/span><span class=\"p\">,()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"m\">0.0<\/span><span class=\"p\">,<\/span>\n            <span class=\"p\">(<\/span><span class=\"n\">i<\/span><span class=\"p\">,<\/span> <span class=\"n\">loopState<\/span><span class=\"p\">,<\/span> <span class=\"n\">partialResult<\/span><span class=\"p\">)<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span> <span class=\"cm\">\/*Do Work*\/<\/span> <span class=\"p\">},<\/span>            \n            <span class=\"p\">(<\/span><span class=\"n\">localPartialSum<\/span><span class=\"p\">)<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span> <span class=\"k\">lock<\/span> <span class=\"p\">(<\/span><span class=\"n\">lockObject<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span> <span class=\"n\">result<\/span> <span class=\"p\">+=<\/span> <span class=\"n\">localPartialSum<\/span> <span class=\"p\">}});<\/span>            \n        <span class=\"k\">return<\/span> <span class=\"n\">result<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h4 id=\"1-million-doubles---result--xx\">1 million doubles - (result += x*x)<\/h4>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Median<\/th>\n      <th>Bytes Allocated\/Op<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>Imperative<\/td>\n      <td>1.1138 ms<\/td>\n      <td>29,480.65<\/td>\n    <\/tr>\n    <tr>\n      <td>LinqParallel<\/td>\n      <td>3.3174 ms<\/td>\n      <td>117,802.56<\/td>\n    <\/tr>\n    <tr>\n      <td>ParallelFor<\/td>\n      <td>1.9985 ms<\/td>\n      <td>59,264.27<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/>   <br \/>\nThe easiest way to parallelize work like this in C# is with <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/dd460688(v=vs.110).aspx\">PLINQ<\/a>.\nJust type your collection name, then <em>.AsParallel()<\/em> and fire away with Linq queries. Unfortunately in this case it does no good, and\nneither does the <em>Parallel.For<\/em> function.  The workload of just squaring doubles and adding them up isn\u2019t enough to get a net benefit\nhere. You would need to roll your own function using ThreadPools or perhaps Threads directly to see a speedup.<\/p>\n\n<h4 id=\"1-million-doubles---result--mathsinx\">1 million doubles - (result += Math.sin(x))<\/h4>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Median<\/th>\n      <th>Bytes Allocated\/Op<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>Imperative<\/td>\n      <td>37.1130 ms<\/td>\n      <td>840,522.92<\/td>\n    <\/tr>\n    <tr>\n      <td>LinqParallel<\/td>\n      <td>9.8497 ms<\/td>\n      <td>225,694.67<\/td>\n    <\/tr>\n    <tr>\n      <td>ParallelFor<\/td>\n      <td>8.5615 ms<\/td>\n      <td>166,386.40<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/>\nWith the bigger workload there is now a large improvement by parallelizing. It takes a CPU about 2 orders of magnitude more cycles to perform a sin operation\nthat it does an add or multiply. Because of this, per-element overhead cost becomes a much smaller percentage of \noverall runtime, and we get the ~4x speedup we expect from 4 physical cores. It also reduces the relative cost of the simple Linq approach compared to the\nmore complex <em>Parallel.For<\/em> abstraction. Consider how big the workload is to help decide if the simple Linq approach is worth the cost.<\/p>\n\n<h3 id=\"fsharp\">FSharp<\/h3>\n\n<p>F# has a number of easy to use 3rd party libraries for this purpose. All can be used from C# as well. \nA quick rundown of them here:<\/p>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>\n    <span class=\"c\">(* Nessos Streams ParStream *)<\/span>\n    <span class=\"kt\">array<\/span>\n    <span class=\"o\">|&gt;<\/span> <span class=\"nn\">ParStream<\/span><span class=\"p\">.<\/span><span class=\"n\">ofArray<\/span>                    \n    <span class=\"o\">|&gt;<\/span> <span class=\"nn\">ParStream<\/span><span class=\"p\">.<\/span><span class=\"n\">fold<\/span> <span class=\"p\">(<\/span><span class=\"k\">fun<\/span> <span class=\"n\">acc<\/span> <span class=\"n\">x<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">acc<\/span> <span class=\"o\">+<\/span> <span class=\"n\">x<\/span><span class=\"o\">*<\/span><span class=\"n\">x<\/span><span class=\"p\">)<\/span>  <span class=\"p\">(<\/span><span class=\"o\">+<\/span><span class=\"p\">)<\/span> <span class=\"p\">(<\/span><span class=\"k\">fun<\/span> <span class=\"bp\">()<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"mi\">0<\/span><span class=\"o\">.<\/span><span class=\"mi\">0<\/span><span class=\"p\">)<\/span> \n\n    <span class=\"c\">(* FSharp.Collections.ParallelSeq *)<\/span>\n    <span class=\"kt\">array<\/span>\n    <span class=\"o\">|&gt;<\/span> <span class=\"nn\">PSeq<\/span><span class=\"p\">.<\/span><span class=\"n\">reduce<\/span> <span class=\"p\">(<\/span><span class=\"k\">fun<\/span> <span class=\"n\">acc<\/span> <span class=\"n\">x<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">acc<\/span><span class=\"o\">+<\/span><span class=\"n\">x<\/span><span class=\"o\">*<\/span><span class=\"n\">x<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"c\">(* SIMDArray (uses AVX2 SIMD as well) *)<\/span>\n    <span class=\"kt\">array<\/span>\n    <span class=\"o\">|&gt;<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"nn\">SIMDParallel<\/span><span class=\"p\">.<\/span><span class=\"n\">fold<\/span> <span class=\"p\">(<\/span><span class=\"k\">fun<\/span> <span class=\"n\">acc<\/span> <span class=\"n\">x<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">acc<\/span> <span class=\"o\">+<\/span> <span class=\"n\">x<\/span><span class=\"o\">*<\/span><span class=\"n\">x<\/span><span class=\"p\">)<\/span>\n                               <span class=\"p\">(<\/span><span class=\"k\">fun<\/span> <span class=\"n\">acc<\/span> <span class=\"n\">x<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">acc<\/span> <span class=\"o\">+<\/span> <span class=\"n\">x<\/span><span class=\"o\">*<\/span><span class=\"n\">x<\/span><span class=\"p\">)<\/span>  \n                               <span class=\"p\">(<\/span><span class=\"o\">+<\/span><span class=\"p\">)<\/span> <span class=\"p\">(<\/span><span class=\"o\">+<\/span><span class=\"p\">)<\/span> <span class=\"mi\">0<\/span><span class=\"o\">.<\/span><span class=\"mi\">0<\/span> \n\n<\/code><\/pre><\/div><\/div>\n\n<h3 id=\"1-million-doubles-result--xx\">1 million doubles (result += x*x)<\/h3>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Time<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>.NET \/ F# Parallel SIMDArray<\/td>\n      <td>0.26ms<\/td>\n    <\/tr>\n    <tr>\n      <td>.NET \/ F# Nessos Streams<\/td>\n      <td>1.05ms<\/td>\n    <\/tr>\n    <tr>\n      <td>.NET \/ F# ParallelSeq<\/td>\n      <td>3.1ms<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<p><a href=\"https:\/\/github.com\/jackmott\/SIMDArray\">SIMDArray<\/a> is \u2018cheating\u2019 here as it also does SIMD operations, but I include it because I wrote it, so I do what I want.\n All of these out perform core library functions above.<\/p>\n\n<h3 id=\"1-million-doubles-result--mathsinx\">1 million doubles (result += Math.Sin(x))<\/h3>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Time<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>.NET \/ F# Nessos Streams<\/td>\n      <td>6.7ms<\/td>\n    <\/tr>\n    <tr>\n      <td>.NET \/ F# ParallelSeq<\/td>\n      <td>9.9ms<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<p>The Sin operation can\u2019t be SIMDified here so SIMDArray is out. Nessos streams again proves to be better than the core library functions.<\/p>\n\n<h3 id=\"c\">C++<\/h3>\n\n<p>Now the same experiment in C++. Most C++ compilers can auto parallelize loops, which you can control via compiler flags or inline hints in your code.  For instance\nwith Visual Studio\u2019s C++ compiler you can just put <em>#pragma loop(hint_parallel(8))<\/em> on top of a loop, and it will parallelize it if it can.  Unfortunately our\ntoy example is (intentionally) a tiny bit too complex for that.  Since we are summing up results, this creates a data dependency. Fortunately we can use <a href=\"http:\/\/openmp.org\/wp\/\">OpenMP<\/a>,\nwhich is available in Microsoft Visual C++, GCC, Clang, and other popular C++ compilers:<\/p>\n\n<div class=\"language-c highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"kt\">double<\/span> <span class=\"n\">result<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">;<\/span>\n    <span class=\"cp\">#pragma omp parallel for reduction(+ : result)\n<\/span>    <span class=\"k\">for<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">COUNT<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span><span class=\"o\">++<\/span><span class=\"p\">)<\/span> \t\n    <span class=\"p\">{<\/span>\n       <span class=\"n\">result<\/span> <span class=\"o\">+=<\/span> <span class=\"cm\">\/*Do Work*\/<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>This is equivalent to the Parallel.For loop used above in C#, where you identify that you will be aggregating data.  This is actually less typing\nand easier to read too, even if the syntax is odd. How does it perform?<\/p>\n\n<h4 id=\"1-million-doubles---result--xx--no-simd\">1 million doubles - (result += x*x)  No SIMD<\/h4>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Median<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>ForLoop<\/td>\n      <td>1.031 ms<\/td>\n    <\/tr>\n    <tr>\n      <td>ParallelizedForLoop<\/td>\n      <td>0.375 ms<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/> \nWe can see that OpenMP is managing a more efficient abstraction than .NET for this case, managing almost almost a 3x speedup where .NET was actually a bit slower.\nNewer OpenMP implementations available on other compiles can also be directed to do SIMD vectorization in the loop for even more speed increase. That does not seem to be available\nin MS Visual C++, and the usual automatic vectorization seems to not happen within the omp loop. Automatic vectorization can be done on the single thread\nfor loop but it was turned off for these C++ tests. <em>The C++ compilers does do older SSE instructions, as is the case with .NET and Java as well, but they only use\na single lane.  MSVC++ will use all lanes if you specify \/fp:fast but only in the non OMP loop<\/em><\/p>\n\n<h4 id=\"1-million-doubles---result--sinx--no-simd\">1 million doubles - (result += sin(x))  No SIMD<\/h4>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Median<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>ForLoop<\/td>\n      <td>10.625 ms<\/td>\n    <\/tr>\n    <tr>\n      <td>ParallelizedForLoop<\/td>\n      <td>2.44 ms<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<p>This time a little more than a 3x speedup, and as you can see the results are overall faster than .NET as well.<\/p>\n\n<h3 id=\"java\">Java<\/h3>\n\n<p>Java\u2019s streams library which performed excellently in a <a href=\"https:\/\/jackmott.github.io\/programming\/2016\/07\/22\/making-obvious-fast.html\">previous blog post<\/a> can be\nused here again. You simply have to tell it you want a parallel stream:<\/p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>\n<span class=\"c1\">\/\/Regular stream<\/span>\n<span class=\"n\">sum<\/span> <span class=\"o\">=<\/span> <span class=\"n\">Arrays<\/span><span class=\"o\">.<\/span><span class=\"na\">stream<\/span><span class=\"o\">(<\/span><span class=\"n\">array<\/span><span class=\"o\">).<\/span><span class=\"na\">reduce<\/span><span class=\"o\">(<\/span><span class=\"mi\">0<\/span><span class=\"o\">,(<\/span><span class=\"n\">acc<\/span><span class=\"o\">,<\/span><span class=\"n\">x<\/span><span class=\"o\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"cm\">\/*Do Work*\/<\/span><span class=\"o\">);<\/span>\n\n<span class=\"c1\">\/\/ParallelStream<\/span>\n<span class=\"n\">sum<\/span> <span class=\"o\">=<\/span> <span class=\"n\">Arrays<\/span><span class=\"o\">.<\/span><span class=\"na\">stream<\/span><span class=\"o\">(<\/span><span class=\"n\">array<\/span><span class=\"o\">).<\/span><span class=\"na\">parallel<\/span><span class=\"o\">().<\/span><span class=\"na\">reduce<\/span><span class=\"o\">(<\/span><span class=\"mi\">0<\/span><span class=\"o\">,(<\/span><span class=\"n\">acc<\/span><span class=\"o\">,<\/span><span class=\"n\">x<\/span><span class=\"o\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"cm\">\/*Do Work*\/<\/span><span class=\"o\">);<\/span>\n\n<\/code><\/pre><\/div><\/div>\n\n<p><br \/><\/p>\n\n<h4 id=\"1-million-doubles-result--xx-1\">1 million doubles (result += x*x)<\/h4>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Median<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>Stream<\/td>\n      <td>1.03ms<\/td>\n    <\/tr>\n    <tr>\n      <td>Parallel Stream<\/td>\n      <td>0.375ms -&gt; .8ms<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<h4 id=\"1-million-doubles-result--mathsinx-1\">1 million doubles (result += Math.sin(x))<\/h4>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Median<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>Stream<\/td>\n      <td>34.5ms<\/td>\n    <\/tr>\n    <tr>\n      <td>Parallel Stream<\/td>\n      <td>7.8ms -&gt; 14ms<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<p>Java performs right on par with C++ in the first example, but falls behind when using Math.sin().  It appears that this is\nnot due to the parallel streams, but due to Java using a more accurate sin implementation, rather than calling the\nx86 instruction directly.  This difference may not exist on other hardware. I do not like it when a langauge tells me I\ncan\u2019t touch the hardware if I want. A Math.NativeSin() would be nice. The streams library overall though has proven to be\nexcellent, matching C++ in both scalar and parallel varieties.<\/p>\n\n<h4 id=\"update\">Update!<\/h4>\n\n<p>Further experiments with Java using the JMH testing framework have shown the parallel streams to exhibit inconsistent performance. \nSometimes executing in ~.375ms indefinitely. Sometimes executing that fast for only a few dozens iterations then suddenly taking ~.8ms \nindefinitely after that. Reasons unknown, if you are a JVM expert and have ideas, please email me.<\/p>\n\n<h3 id=\"javascript\">Javascript<\/h3>\n\n<p>pfffftttt (yeah I know about Web Workers)<\/p>\n\n<h3 id=\"rust\">Rust<\/h3>\n\n<p>Rust provides no easy loop parallelizing abstractions out of the box, you have to roll your own. OpenMP style\nfeatures <a href=\"https:\/\/github.com\/rust-lang\/rfcs\/issues\/859\">may be in the works for Rust<\/a> though, and 3rd party libraries are available.\nSo let\u2019s take a look at a nice one called <a href=\"https:\/\/github.com\/nikomatsakis\/rayon\">Rayon<\/a> which adds a \u201cpar_iter\u201d providing similar\nfunctions as the regular iter, but in parallel.  The code remains very simple:<\/p>\n\n<div class=\"language-rust highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    \n    <span class=\"c\">\/\/ The regular iter<\/span>\n    <span class=\"n\">vector<\/span><span class=\"nf\">.iter<\/span><span class=\"p\">()<\/span><span class=\"nf\">.map<\/span><span class=\"p\">(|<\/span><span class=\"o\">&amp;<\/span><span class=\"n\">x<\/span><span class=\"p\">|<\/span> <span class=\"cm\">\/* do work *\/<\/span><span class=\"p\">)<\/span><span class=\"nf\">.sum<\/span><span class=\"p\">()<\/span>\n\n    <span class=\"c\">\/\/ Parallel iter<\/span>\n    <span class=\"n\">vector<\/span><span class=\"nf\">.par_iter<\/span><span class=\"p\">()<\/span><span class=\"nf\">.map<\/span><span class=\"p\">(|<\/span><span class=\"o\">&amp;<\/span><span class=\"n\">x<\/span><span class=\"p\">|<\/span> <span class=\"cm\">\/* do work *\/<\/span><span class=\"p\">)<\/span><span class=\"nf\">.sum<\/span><span class=\"p\">()<\/span>\n\n<\/code><\/pre><\/div><\/div>\n\n<p><br \/><\/p>\n\n<h4 id=\"1-million-doubles-result--xx-2\">1 million doubles (result += x*x)<\/h4>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Median<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>iter<\/td>\n      <td>1.05 ms<\/td>\n    <\/tr>\n    <tr>\n      <td>par_iter<\/td>\n      <td>.375 ms<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<h4 id=\"1-million-doubles-result--mathsinx-2\">1 million doubles (result += Math.sin(x))<\/h4>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Median<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>iter<\/td>\n      <td>9.65 ms<\/td>\n    <\/tr>\n    <tr>\n      <td>par_iter<\/td>\n      <td>2.44 ms<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<p>These are excellent results, tied with C++, and requiring only a single line of code to express.<\/p>\n\n<h2 id=\"summary\">Summary<\/h2>\n\n<p>The loop abstractions examined here are just one type of parallel or concurrent programming abstraction available. There is\na whole universe out there, Actor Models, Async\/Await, Tasks, Thread Pools, and so on.  Be sure to understand what you are using,\nand measure whether it will really be useful, or whether you should focus on fast single threaded algorithms or look for third party\ntools with better performance.<\/p>\n\n<h2 id=\"aggregated-testing-results\">Aggregated Testing Results<\/h2>\n\n<h4 id=\"1-million-doubles--result--xx--no-simd--except-simdarray\">1 million doubles ( result += x*x)  No SIMD ( Except SIMDArray)<\/h4>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Time<\/th>\n      <th>Lines Of Code<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>.NET \/ F# SIMDArray<\/td>\n      <td>0.26ms<\/td>\n      <td>1<\/td>\n    <\/tr>\n    <tr>\n      <td>Rust Rayon<\/td>\n      <td>0.375ms<\/td>\n      <td>1<\/td>\n    <\/tr>\n    <tr>\n      <td>C++ OpenMP<\/td>\n      <td>0.375ms<\/td>\n      <td>~5<\/td>\n    <\/tr>\n    <tr>\n      <td>Java Parallel Streams<\/td>\n      <td>0.375 ms -&gt; 0.8ms<\/td>\n      <td>1<\/td>\n    <\/tr>\n    <tr>\n      <td>.NET \/ F# Nessos Streams<\/td>\n      <td>1.05ms<\/td>\n      <td>~2<\/td>\n    <\/tr>\n    <tr>\n      <td>.NET Parallel.For<\/td>\n      <td>1.9ms<\/td>\n      <td>~6<\/td>\n    <\/tr>\n    <tr>\n      <td>.NET \/ F# ParallelSeq<\/td>\n      <td>3.1ms<\/td>\n      <td>1<\/td>\n    <\/tr>\n    <tr>\n      <td>.NET Parallel Linq (Sum)<\/td>\n      <td>3.3ms<\/td>\n      <td>1<\/td>\n    <\/tr>\n    <tr>\n      <td>.NET Parallel Linq (Aggregate)<\/td>\n      <td>8ms<\/td>\n      <td>1<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<h4 id=\"1-million-doubles--result--sinx--no-simd\">1 million doubles ( result += sin(x))  No SIMD<\/h4>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Time<\/th>\n      <th>Lines Of Code<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>Rust Rayon<\/td>\n      <td>2.44ms<\/td>\n      <td>1<\/td>\n    <\/tr>\n    <tr>\n      <td>C++ OpenMP<\/td>\n      <td>2.44ms<\/td>\n      <td>~4<\/td>\n    <\/tr>\n    <tr>\n      <td>.NET \/ F# Nessos Streams<\/td>\n      <td>6.7ms<\/td>\n      <td>~2<\/td>\n    <\/tr>\n    <tr>\n      <td>Java Parallel Streams<\/td>\n      <td>7.8ms -&gt; 14ms<\/td>\n      <td>1<\/td>\n    <\/tr>\n    <tr>\n      <td>.NET Parallel.For<\/td>\n      <td>8.5615ms<\/td>\n      <td>~6<\/td>\n    <\/tr>\n    <tr>\n      <td>.NET Parallel Linq (Sum)<\/td>\n      <td>9.8497ms<\/td>\n      <td>1<\/td>\n    <\/tr>\n    <tr>\n      <td>.NET \/ F# ParallelSeq<\/td>\n      <td>9.9ms<\/td>\n      <td>1<\/td>\n    <\/tr>\n    <tr>\n      <td>.NET Parallel Linq (Aggregate)<\/td>\n      <td>45.6ms<\/td>\n      <td>1<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<h2 id=\"benchmark-details\">Benchmark Details<\/h2>\n\n<p>All benchmarks run with what I believe to be the latest and greatest compilers available for Windows for each language (Debateable for C++). \nJIT warmup time is accounted for when\napplicable. If you identify cases where code or compiler\/environment choices are sub optimal, email me please.<\/p>\n\n<h4 id=\"environment\">Environment<\/h4>\n<div class=\"language-ini highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"err\">Host<\/span> <span class=\"err\">Process<\/span> <span class=\"err\">Environment<\/span> <span class=\"err\">Information:<\/span>\n<span class=\"py\">BenchmarkDotNet<\/span><span class=\"p\">=<\/span><span class=\"s\">v0.9.8.0<\/span>\n<span class=\"py\">OS<\/span><span class=\"p\">=<\/span><span class=\"s\">Microsoft Windows NT 6.2.9200.0<\/span>\n<span class=\"py\">Processor<\/span><span class=\"p\">=<\/span><span class=\"s\">Intel(R) Core(TM) i7-4712HQ CPU 2.30GHz, ProcessorCount=8<\/span>\n<span class=\"py\">Frequency<\/span><span class=\"p\">=<\/span><span class=\"s\">2240907 ticks, Resolution=446.2479 ns, Timer=TSC<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h4 id=\"f--c-runtime-details\">F# \/ C# Runtime Details<\/h4>\n<div class=\"language-ini highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"py\">CLR<\/span><span class=\"p\">=<\/span><span class=\"s\">MS.NET 4.0.30319.42000, Arch=64-bit RELEASE [RyuJIT]<\/span>\n<span class=\"py\">GC<\/span><span class=\"p\">=<\/span><span class=\"s\">Concurrent Workstation<\/span>\n<span class=\"py\">JitModules<\/span><span class=\"p\">=<\/span><span class=\"s\">clrjit-v4.6.1590.0<\/span>\n<span class=\"py\">Type<\/span><span class=\"p\">=<\/span><span class=\"s\">SIMDBenchmark  Mode=Throughput  Platform=X64  <\/span>\n<span class=\"py\">Jit<\/span><span class=\"p\">=<\/span><span class=\"s\">RyuJit  GarbageCollection=Concurrent Workstation  <\/span>\n\n<\/code><\/pre><\/div><\/div>\n\n<h3 id=\"c-details\">C++ Details<\/h3>\n<p>Visual Studio 2015 Update 3, Optimizations set for maximum speed, SIMD off<\/p>\n\n<h3 id=\"java-details\">Java Details<\/h3>\n<p>Oracle Java 64bit version 8 update 102\nTesting done with JMH<\/p>\n\n<h3 id=\"rust-details\">Rust Details<\/h3>\n<p>rustc 1.13.0-nightly\nbuild with <code class=\"highlighter-rouge\">cargo rustc --release -- -C lto -C target-cpu=native<\/code><\/p>\n","pubDate":"Tue, 30 Aug 2016 19:17:27 +0000","link":"https:\/\/jackmott.github.io\/\/programming\/2016\/08\/30\/think-before-you-parallelize.html","guid":"https:\/\/jackmott.github.io\/\/programming\/2016\/08\/30\/think-before-you-parallelize.html","category":"programming"},{"title":"When Big O Fools Ya","description":"<p>Big O notation is a great tool.  It allows one to quickly make smart choices among various data structures and algorithms.  But sometimes a casual\nBig O analysis can fool us if we don\u2019t think carefully about the impact of constant factors. One such example comes up very often\nwhen programming on modern CPUs, and that is when choosing between an Array, and a List, or Tree type structure.<\/p>\n\n<h3 id=\"memory-slow-slow-memory\">Memory, Slow Slow Memory<\/h3>\n\n<p>In the early 1980s, the time it took to get data from RAM, and the time it took to do computation on the data were roughly in parity.  You could \nuse algorithms that hop randomly over the heap, grabbing data and working with it.  Since that time, CPUs have gotten faster at a much higher rate\nthan RAM has.  Today, a CPU can compute on the order of 100 to 1000 times faster than it can get data from RAM. This means when the cpu needs data from \nRAM it has to stall for hundreds of cycles, doing nothing.  Obviously this would be a useless situation, so modern CPUs have various levels of cache built in.\nAny time you request one piece of data from RAM, you also get chunks of contiguous memory pulled into the caches on the CPU. The result is that when you iterate\nover contiguous memory, you can access it about as fast as the CPU can operate, because you will be streaming chunks of data into the L1 cache.  If you iterate\nover memory in random locations, you will often miss the CPU caches, and performance can suffer greatly.  If you want to learn more about this, \n<a href=\"https:\/\/www.youtube.com\/watch?v=rX0ItVEVjHc\">Mike Acton\u2019s CppCon talk<\/a> is a great starting point and great fun too.<\/p>\n\n<p>The consequence of this is that arrays have become the go to data structure if performance is important, sometimes even when Big O analysis suggests it would be slower. Where you wanted a Tree\nbefore you may want a sorted array and a binary search algorithm. Where you wanted a Queue before you may want a growable array, and so on.<\/p>\n\n<h3 id=\"linked-list-vs-array-list\">Linked List vs Array List<\/h3>\n\n<p>Once you are familiar with how important contiguous memory access is, it should be no surprise that if you want to iterate over a collection quickly, that an array will be faster than\na Linked List.  Environments with clever allocators and garbage collectors may be able to keep Linked List nodes somewhat contiguous, some of the time, but they can\u2019t guarantee it.  Using a raw\narray usually involves quite a bit more complex code, especially if you want to be able to insert or add items, as you will have to deal with growing the array, shuffling elements around, and so on.\nMost language\u2019s have core libraries which include some sort of growable array data structure to help with this.  In C++ you have <a href=\"http:\/\/www.cplusplus.com\/reference\/vector\/vector\/\">vector<\/a>, in C# you have\n<a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/6sh2ey19(v=vs.110).aspx\">List&lt;T&gt; (aliased as ResizeArray in F#)<\/a>, and in Java there is <a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/util\/ArrayList.html\">ArrayList<\/a>. Usually \nthese data structures expose the same, or similar interface as the Linked List collection.  <strong>I will refer to such data structures as Array Lists from here on, but keep in mind all the C# examples are using the List&lt;T&gt; class, not the older ArrayList class.<\/strong><\/p>\n\n<p>So what if you need a data structure that you can insert items into, and iterate over quickly? Let us assume for this example, that we have a use case where we will insert into the front\nof a collection about 5 times more often that we iterate over it. Let us also assume that the Linked List and Array List in our environment have interfaces which are equally pleasant to work with for this task.\nAll that remains then to make a choice is to determine which one performs better.  In the interest of optimizing our own valuable time, one might turn to Big O analysis.  Referring to the handy \n<a href=\"http:\/\/bigocheatsheet.com\/\">Big-O Cheat Sheet<\/a>, the relevant time complexities for these two data structures are:<\/p>\n\n<table>\n  <thead>\n    <tr>\n      <th>\u00a0<\/th>\n      <th>Iterate<\/th>\n      <th>Insert<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>Array List<\/td>\n      <td>O(n)<\/td>\n      <td>O(n)<\/td>\n    <\/tr>\n    <tr>\n      <td>Linked List<\/td>\n      <td>O(n)<\/td>\n      <td>O(1)<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/>\nArray Lists are problematic for insertion, at a minimum it has to copy every single element beyond the insertion point in the array to move them over by 1 to make space for the inserted element, making it O(n). Sometimes it will\nalso have to reallocate a new, bigger array to make room for the insertion.  This doesn\u2019t change the Big O time complexity, but does take time, and waste memory.  So it seems for our use case, where\ninsert happens 5 times more often than iterating, that the best choice is clear.  As long as n is large enough, Linked List should perform better overall.<\/p>\n\n<h3 id=\"empiricism\">Empiricism<\/h3>\n\n<p>But, to know things for sure, we always have to count. So let us do an experiment in C#, using <a href=\"https:\/\/github.com\/PerfDotNet\/BenchmarkDotNet\">BenchMarkDotNet<\/a>. C# provides generic collections\nLinkedList<T> which is a classic Linked List, and List<T> which is an Array List. Their interfaces are similar, and both allow us to implement our use case with ease.  We will assume a worst case scenario for\nArray List, by always inserting at the front, necessitating that the entire array be copied on each insertion. The testing environment specs are:<\/T><\/T><\/p>\n\n<div class=\"language-ini highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"err\">Host<\/span> <span class=\"err\">Process<\/span> <span class=\"err\">Environment<\/span> <span class=\"err\">Information:<\/span>\n<span class=\"py\">BenchmarkDotNet.Core<\/span><span class=\"p\">=<\/span><span class=\"s\">v0.9.9.0<\/span>\n<span class=\"py\">OS<\/span><span class=\"p\">=<\/span><span class=\"s\">Microsoft Windows NT 6.2.9200.0<\/span>\n<span class=\"py\">Processor<\/span><span class=\"p\">=<\/span><span class=\"s\">Intel(R) Core(TM) i7-4712HQ CPU 2.30GHz, ProcessorCount=8<\/span>\n<span class=\"py\">Frequency<\/span><span class=\"p\">=<\/span><span class=\"s\">2240910 ticks, Resolution=446.2473 ns, Timer=TSC<\/span>\n<span class=\"py\">CLR<\/span><span class=\"p\">=<\/span><span class=\"s\">MS.NET 4.0.30319.42000, Arch=64-bit RELEASE [RyuJIT]<\/span>\n<span class=\"py\">GC<\/span><span class=\"p\">=<\/span><span class=\"s\">Concurrent Workstation<\/span>\n<span class=\"py\">JitModules<\/span><span class=\"p\">=<\/span><span class=\"s\">clrjit-v4.6.1590.0<\/span>\n\n<span class=\"py\">Type<\/span><span class=\"p\">=<\/span><span class=\"s\">Bench  Mode=Throughput  <\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h3 id=\"test-cases\">Test Cases:<\/h3>\n\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"p\">[<\/span><span class=\"nf\">Benchmark<\/span><span class=\"p\">(<\/span><span class=\"n\">Baseline<\/span><span class=\"p\">=<\/span><span class=\"k\">true<\/span><span class=\"p\">)]<\/span>\n    <span class=\"k\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">ArrayTest<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>        \n        <span class=\"c1\">\/\/In C#, List&lt;T&gt; is an array backed list.<\/span>\n        <span class=\"n\">List<\/span><span class=\"p\">&lt;<\/span><span class=\"kt\">int<\/span><span class=\"p\">&gt;<\/span> <span class=\"n\">local<\/span> <span class=\"p\">=<\/span> <span class=\"n\">arrayList<\/span><span class=\"p\">;<\/span>\n        <span class=\"kt\">int<\/span> <span class=\"n\">localInserts<\/span> <span class=\"p\">=<\/span> <span class=\"n\">inserts<\/span><span class=\"p\">;<\/span>\n        <span class=\"kt\">int<\/span> <span class=\"n\">sum<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span>\n        <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"p\">&lt;<\/span> <span class=\"n\">localInserts<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span><span class=\"p\">++)<\/span>\n        <span class=\"p\">{<\/span>\n            <span class=\"n\">local<\/span><span class=\"p\">.<\/span><span class=\"nf\">Insert<\/span><span class=\"p\">(<\/span><span class=\"m\">0<\/span><span class=\"p\">,<\/span> <span class=\"m\">1<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/Insert the number 1 at the front<\/span>\n        <span class=\"p\">}<\/span>\n\n        <span class=\"c1\">\/\/ For loops iterate over List&lt;T&gt; much faster than foreach<\/span>\n        <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"p\">&lt;<\/span> <span class=\"n\">local<\/span><span class=\"p\">.<\/span><span class=\"n\">Count<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span><span class=\"p\">++)<\/span>\n        <span class=\"p\">{<\/span>\n            <span class=\"n\">sum<\/span> <span class=\"p\">+=<\/span> <span class=\"n\">local<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">];<\/span>  <span class=\"c1\">\/\/do some work here so the JIT doesn't elide the loop entirely<\/span>\n        <span class=\"p\">}<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">sum<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"p\">[<\/span><span class=\"n\">Benchmark<\/span><span class=\"p\">]<\/span>\n    <span class=\"k\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">ListTest<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"n\">LinkedList<\/span><span class=\"p\">&lt;<\/span><span class=\"kt\">int<\/span><span class=\"p\">&gt;<\/span> <span class=\"n\">local<\/span> <span class=\"p\">=<\/span> <span class=\"n\">linkedList<\/span><span class=\"p\">;<\/span>\n        <span class=\"kt\">int<\/span> <span class=\"n\">localInserts<\/span> <span class=\"p\">=<\/span> <span class=\"n\">inserts<\/span><span class=\"p\">;<\/span>\n        <span class=\"kt\">int<\/span> <span class=\"n\">sum<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span>\n        <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"p\">&lt;<\/span> <span class=\"n\">localInserts<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span><span class=\"p\">++)<\/span>\n        <span class=\"p\">{<\/span>\n            <span class=\"n\">local<\/span><span class=\"p\">.<\/span><span class=\"nf\">AddFirst<\/span><span class=\"p\">(<\/span><span class=\"m\">1<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/Insert the number 1 at the front<\/span>\n        <span class=\"p\">}<\/span>\n\n        <span class=\"c1\">\/\/ Again, iterating the fastest possible way over this collection<\/span>\n        <span class=\"kt\">var<\/span> <span class=\"n\">node<\/span> <span class=\"p\">=<\/span> <span class=\"n\">local<\/span><span class=\"p\">.<\/span><span class=\"n\">First<\/span><span class=\"p\">;<\/span>\n        <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"p\">&lt;<\/span> <span class=\"n\">local<\/span><span class=\"p\">.<\/span><span class=\"n\">Count<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span><span class=\"p\">++)<\/span>\n        <span class=\"p\">{<\/span>\n            <span class=\"n\">sum<\/span> <span class=\"p\">+=<\/span> <span class=\"n\">node<\/span><span class=\"p\">.<\/span><span class=\"n\">Value<\/span><span class=\"p\">;<\/span>\n            <span class=\"n\">node<\/span> <span class=\"p\">=<\/span> <span class=\"n\">node<\/span><span class=\"p\">.<\/span><span class=\"n\">Next<\/span><span class=\"p\">;<\/span>\n        <span class=\"p\">}<\/span>\n\n        <span class=\"k\">return<\/span> <span class=\"n\">sum<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h3 id=\"results\">Results:<\/h3>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>length<\/th>\n      <th>inserts<\/th>\n      <th>Median<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>ArrayTest<\/td>\n      <td>100<\/td>\n      <td>5<\/td>\n      <td>38.9983 us<\/td>\n    <\/tr>\n    <tr>\n      <td>ListTest<\/td>\n      <td>100<\/td>\n      <td>5<\/td>\n      <td>51.7538 us<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<p>The Array List wins by a nice margin. But this is a small list, Big O only tells us about performance as <code class=\"highlighter-rouge\">n<\/code> grows large, so we should see this trend eventually reverse as <code class=\"highlighter-rouge\">n<\/code> grows larger. \nLet\u2019s try it:<\/p>\n\n<div style=\"width:750px;\">\n<div style=\"width:350px;float:left;\">\n<table>\n  <thead>\n    <tr>      \n      <th>Method<\/th>\n      <th>Length<\/th>\n      <th>Inserts<\/th>\n      <th>Median<\/th>\n      \n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>ArrayTest<\/td>\n      <td>100<\/td>\n      <td>5<\/td>\n      <td>38.9983 us<\/td>      \n    <\/tr>\n    <tr>\n      <td>ListTest<\/td>\n      <td>100<\/td>\n      <td>5<\/td>\n      <td>51.7538 us<\/td>      \n    <\/tr>\n    <tr>\n      <td>ArrayTest<\/td>\n      <td>1000<\/td>\n      <td>5<\/td>\n      <td>42.1585 us<\/td>      \n    <\/tr>\n    <tr>\n      <td>ListTest<\/td>\n      <td>1000<\/td>\n      <td>5<\/td>\n      <td>49.5561 us<\/td>      \n    <\/tr>\n    <tr>\n      <td>ArrayTest<\/td>\n      <td>100000<\/td>\n      <td>5<\/td>\n      <td>208.9662 us<\/td>      \n    <\/tr>\n    <tr>\n      <td>ListTest<\/td>\n      <td>100000<\/td>\n      <td>5<\/td>\n      <td>312.2153 us<\/td>      \n    <\/tr>\n    <tr>\n      <td>ArrayTest<\/td>\n      <td>1000000<\/td>\n      <td>5<\/td>\n      <td>2,179.2469 us<\/td>      \n    <\/tr>\n    <tr>\n      <td>ListTest<\/td>\n      <td>1000000<\/td>\n      <td>5<\/td>\n      <td>4,913.3430 us<\/td>      \n    <\/tr>\n    <tr>\n      <td>ArrayTest<\/td>\n      <td>10000000<\/td>\n      <td>5<\/td>\n      <td>36,103.8456 us<\/td>      \n    <\/tr>\n    <tr>\n      <td>ListTest<\/td>\n      <td>10000000<\/td>\n      <td>5<\/td>\n      <td>49,395.0839 us<\/td>      \n    <\/tr>\n  <\/tbody>\n<\/table>\n<\/div>\n<div style=\"width:400px;float:right\">\n\n<table class=\"highchart\" data-graph-container=\".. .. .highchart-container\" data-graph-type=\"line\" graph-color=\"#000\" data-graph-xaxis-title-text=\"array size\" data-graph-yaxis1-title-text=\"log runtime us\" style=\"display:none\">\n  <thead>\n    <tr>      \n      <th>Length<\/th>      \n      <th>ArrayList<\/th>\n      <th>LinkedList<\/th>      \n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>100<\/td>                  \n      <td>38.9983<\/td>\n      <td>51.7538<\/td>      \n    <\/tr>    \n    <tr>      \n      <td>1000<\/td>      \n      <td>42.1585<\/td>\n      <td>49.5561<\/td>\n    <\/tr>    \n    <tr>      \n      <td>100000<\/td>      \n      <td>208.9662<\/td>\n      <td>312.2153<\/td>\n    <\/tr>    \n    <tr>      \n      <td>1000000<\/td>      \n      <td>2179.2469<\/td>\n      <td>4913.3430<\/td>      \n    <\/tr>    \n    <tr>    \n      <td>10000000<\/td>    \n      <td>36103.8456<\/td>\n      <td>49395.0839<\/td>\n    <\/tr>\n    \n  <\/tbody>\n<\/table>\n<div class=\"highchart-container\" style=\"background-color:#000;\"><\/div>\n<\/div>\n<div style=\"clear:both;\"><\/div>\n<\/div>\n\n<p><br \/>\nHere we get the result that will be counterintuitive to many. No matter how large <code class=\"highlighter-rouge\">n<\/code> gets, the Array List still performs better overall. In order for performance to get worse, the <em>ratio<\/em>\nof inserts to iterations has to change, not just the length of the collection. Note that isn\u2019t an actual failure of Big O analysis, it is merely a common human failure in our application of it.  If you\nactually \u201cdid the math\u201d, Big O would tell you that the two data structures here will grow at the same speed when there is a constant ratio of inserts to iterations.<\/p>\n\n<p>Where the break even point occurs will depend on many factors, though a good rule of thumb suggested by \n<a href=\"https:\/\/www.youtube.com\/watch?v=fHNmRkzxHWs\">Chandler Carruth<\/a> at Google is that Array Lists will outperform Linked Lists until you are inserting about an order of magnitude more often than you are iterating. \nThis rule of thumb works well in this particular case, as 10:1 is where we see Array List start to lose:<\/p>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Length<\/th>\n      <th>Inserts<\/th>\n      <th>Median<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>ArrayTest<\/td>\n      <td>100000<\/td>\n      <td>10<\/td>\n      <td>328,147.7954 ns<\/td>\n    <\/tr>\n    <tr>\n      <td>ListTest<\/td>\n      <td>100000<\/td>\n      <td>10<\/td>\n      <td>324,349.0560 ns<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<h3 id=\"devils-in-the-details\">Devils in the Details<\/h3>\n\n<p>The reason Array List wins here is because the integers being iterated over are lined up contiguously in memory. Each time an integer is requested from memory an entire cache line of integers is pulled into the L1\ncache, so the next 64 bytes\nof data are ready to go. With the Linked List, each call to <code class=\"highlighter-rouge\">node.Next<\/code> makes a pointer hop to the next node, and there is no guarantee that nodes will be contiguous in memory.  Therefore we will \nmiss the cache sometimes.  But we aren\u2019t always iterating over value types like this,  especially in OOP oriented managed languages we often iterate over reference types.  In that case, even with an Array List, while the \npointers themselves are contiguous in memory, the objects they point to are not. The situation is still better than with a Linked List, where you will be making two pointer hops per iteration instead of one, \nbut how does this affect the relative performance?<\/p>\n\n<p>It narrows it quite a bit, depending on the size of the objects, and the details of your hardware and software environment. Refactoring the example above to use Lists of small objects (12 bytes), the break even\npoint drops to about 4 inserts per iteration:<\/p>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Length<\/th>\n      <th>Inserts<\/th>\n      <th>Median<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>ArrayTestObject<\/td>\n      <td>100000<\/td>\n      <td>0<\/td>\n      <td>674.1864 us<\/td>\n    <\/tr>\n    <tr>\n      <td>ListTestObject<\/td>\n      <td>100000<\/td>\n      <td>0<\/td>\n      <td>1,140.9044 us<\/td>\n    <\/tr>\n    <tr>\n      <td>ArrayTestObject<\/td>\n      <td>100000<\/td>\n      <td>2<\/td>\n      <td>959.0482 us<\/td>\n    <\/tr>\n    <tr>\n      <td>ListTestObject<\/td>\n      <td>100000<\/td>\n      <td>2<\/td>\n      <td>1,121.5423 us<\/td>\n    <\/tr>\n    <tr>\n      <td>ArrayTestObject<\/td>\n      <td>100000<\/td>\n      <td>4<\/td>\n      <td>1,230.6550 us<\/td>\n    <\/tr>\n    <tr>\n      <td>ListTestObject<\/td>\n      <td>100000<\/td>\n      <td>4<\/td>\n      <td>1,142.6658 us<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<p>Managed C# code suffers a bit in this case because iterating over this Array List incurs some unnecessary array bounds checking. C++ vector would likely fare better.  If you were really aggressive about this you\ncould probably write a faster Array List class using unsafe C# code to avoid the array bounds checks.  Also, the relative differences here will depend greatly on how your allocator and garbage collector manage the heap, \nhow big your objects are, and other factors.  Larger objects tended to cause the relative performance of the Array List to improve in my environment. In the context of a complete application the relative performance\nof Array List might improve as well as the heap gets more fragmented, but you will have to test to know for sure.<\/p>\n\n<p>As an aside, if your objects are sufficiently small (16 to 32 bytes or less, depending on various factors) you should consider  making them value types (<code class=\"highlighter-rouge\">struct<\/code> in .NET) instead of objects. \nNot only will you benefit greatly from contiguous memory access, but you will potentially reduce garbage collection overhead as well, depending on your usage of them:<\/p>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Length<\/th>\n      <th>Inserts<\/th>\n      <th>Median<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>ArrayTestObject<\/td>\n      <td>100000<\/td>\n      <td>10<\/td>\n      <td>2,094.8273 us<\/td>\n    <\/tr>\n    <tr>\n      <td>ListTestObject<\/td>\n      <td>100000<\/td>\n      <td>10<\/td>\n      <td>1,154.3014 us<\/td>\n    <\/tr>\n    <tr>\n      <td>ArrayTestStruct<\/td>\n      <td>100000<\/td>\n      <td>10<\/td>\n      <td>792.0004 us<\/td>\n    <\/tr>\n    <tr>\n      <td>ListTestStruct<\/td>\n      <td>100000<\/td>\n      <td>10<\/td>\n      <td>1,206.0713 us<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<p>Java may handle this better since it does some automatic cleverness with small objects, or you may have to just use separate arrays of primitive types.  Though onerous to type, \n<a href=\"https:\/\/software.intel.com\/en-us\/articles\/memory-layout-transformations\">this can sometimes be faster<\/a> than an array of structs, depending on your data access patterns.  Consider it when performance matters.<\/p>\n\n<h3 id=\"make-sure-the-abstraction-is-worth-it\">Make Sure the Abstraction is Worth It<\/h3>\n\n<p>It is common for people to object to these sorts of considerations on the basis of code clarity, correctness, and maintainability.  Of course each problem domain has it\u2019s own\npriorities, but I feel strongly that when the clarity benefit of the abstraction is small, and the performance impact is large, that we should choose better performance as a rule.\nBy taking time to understand your environment, you will be aware of cases where a faster but equally clear option exists, as is often the case with Array Lists vs Lists.<\/p>\n\n<p>As some food for thought, here are 7 different ways to add up a list of numbers in C#, with their run times and memory costs. \nChecked arithmetic is used in all cases to keep the comparison with Linq fair, as it\u2019s Sum method uses checked arithmetic. Notice how <em>much<\/em> better performing the fastest option is. \nNotice how expensive the most popular method (Linq) is. Notice \nthat the <code class=\"highlighter-rouge\">foreach<\/code> abstraction works out well with raw Arrays, but not with Array List or Linked List.  Whatever your language and environment of choice is, understand these details so you can \nmake smart default choices.<\/p>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Length<\/th>\n      <th>Median<\/th>\n      <th>Bytes Allocated\/Op<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>LinkedListLinq<\/td>\n      <td>100000<\/td>\n      <td>990.7718 us<\/td>\n      <td>23,192.49<\/td>\n    <\/tr>\n    <tr>\n      <td>RawArrayLinq<\/td>\n      <td>100000<\/td>\n      <td>643.8204 us<\/td>\n      <td>11,856.39<\/td>\n    <\/tr>\n    <tr>\n      <td>LinkedListForEach<\/td>\n      <td>100000<\/td>\n      <td>489.7294 us<\/td>\n      <td>11,909.99<\/td>\n    <\/tr>\n    <tr>\n      <td>LinkedListFor<\/td>\n      <td>100000<\/td>\n      <td>299.9746 us<\/td>\n      <td>6,033.70<\/td>\n    <\/tr>\n    <tr>\n      <td>ArrayListForEach<\/td>\n      <td>100000<\/td>\n      <td>270.3873 us<\/td>\n      <td>6,035.88<\/td>\n    <\/tr>\n    <tr>\n      <td>ArrayListFor<\/td>\n      <td>100000<\/td>\n      <td>97.0850 us<\/td>\n      <td>1,574.32<\/td>\n    <\/tr>\n    <tr>\n      <td>RawArrayForEach<\/td>\n      <td>100000<\/td>\n      <td>53.0535 us<\/td>\n      <td>1,574.84<\/td>\n    <\/tr>\n    <tr>\n      <td>RawArrayFor<\/td>\n      <td>100000<\/td>\n      <td>53.1745 us<\/td>\n      <td>1,577.77<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"p\">[<\/span><span class=\"nf\">Benchmark<\/span><span class=\"p\">(<\/span><span class=\"n\">Baseline<\/span> <span class=\"p\">=<\/span> <span class=\"k\">true<\/span><span class=\"p\">)]<\/span>\n    <span class=\"k\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">LinkedListLinq<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"kt\">var<\/span> <span class=\"n\">local<\/span> <span class=\"p\">=<\/span> <span class=\"n\">linkedList<\/span><span class=\"p\">;<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">local<\/span><span class=\"p\">.<\/span><span class=\"nf\">Sum<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"p\">[<\/span><span class=\"n\">Benchmark<\/span><span class=\"p\">]<\/span>\n    <span class=\"k\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">LinkedListForEach<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"kt\">var<\/span> <span class=\"n\">local<\/span> <span class=\"p\">=<\/span> <span class=\"n\">linkedList<\/span><span class=\"p\">;<\/span>\n        <span class=\"kt\">int<\/span> <span class=\"n\">sum<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span>\n        <span class=\"k\">checked<\/span>\n        <span class=\"p\">{<\/span>\n            <span class=\"k\">foreach<\/span> <span class=\"p\">(<\/span><span class=\"kt\">var<\/span> <span class=\"n\">node<\/span> <span class=\"k\">in<\/span> <span class=\"n\">local<\/span><span class=\"p\">)<\/span>\n            <span class=\"p\">{<\/span>\n                <span class=\"n\">sum<\/span> <span class=\"p\">+=<\/span> <span class=\"n\">node<\/span><span class=\"p\">;<\/span>\n            <span class=\"p\">}<\/span>\n        <span class=\"p\">}<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">sum<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"p\">[<\/span><span class=\"n\">Benchmark<\/span><span class=\"p\">]<\/span>\n    <span class=\"k\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">LinkedListFor<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"kt\">var<\/span> <span class=\"n\">local<\/span> <span class=\"p\">=<\/span> <span class=\"n\">linkedList<\/span><span class=\"p\">;<\/span>\n        <span class=\"kt\">int<\/span> <span class=\"n\">sum<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span>\n        <span class=\"kt\">var<\/span> <span class=\"n\">node<\/span> <span class=\"p\">=<\/span> <span class=\"n\">local<\/span><span class=\"p\">.<\/span><span class=\"n\">First<\/span><span class=\"p\">;<\/span>\n        <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"p\">&lt;<\/span> <span class=\"n\">local<\/span><span class=\"p\">.<\/span><span class=\"n\">Count<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span><span class=\"p\">++)<\/span>\n        <span class=\"p\">{<\/span>\n            <span class=\"k\">checked<\/span>\n            <span class=\"p\">{<\/span>\n                <span class=\"n\">sum<\/span> <span class=\"p\">+=<\/span> <span class=\"n\">node<\/span><span class=\"p\">.<\/span><span class=\"n\">Value<\/span><span class=\"p\">;<\/span>\n                <span class=\"n\">node<\/span> <span class=\"p\">=<\/span> <span class=\"n\">node<\/span><span class=\"p\">.<\/span><span class=\"n\">Next<\/span><span class=\"p\">;<\/span>\n            <span class=\"p\">}<\/span>\n        <span class=\"p\">}<\/span>\n\n        <span class=\"k\">return<\/span> <span class=\"n\">sum<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"p\">[<\/span><span class=\"n\">Benchmark<\/span><span class=\"p\">]<\/span>\n    <span class=\"k\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">ArrayListFor<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/In C#, List&lt;T&gt; is an array backed list<\/span>\n        <span class=\"n\">List<\/span><span class=\"p\">&lt;<\/span><span class=\"kt\">int<\/span><span class=\"p\">&gt;<\/span> <span class=\"n\">local<\/span> <span class=\"p\">=<\/span> <span class=\"n\">arrayList<\/span><span class=\"p\">;<\/span>\n        <span class=\"kt\">int<\/span> <span class=\"n\">sum<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span>\n\n        <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"p\">&lt;<\/span> <span class=\"n\">local<\/span><span class=\"p\">.<\/span><span class=\"n\">Count<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span><span class=\"p\">++)<\/span>\n        <span class=\"p\">{<\/span>\n            <span class=\"k\">checked<\/span>\n            <span class=\"p\">{<\/span>\n                <span class=\"n\">sum<\/span> <span class=\"p\">+=<\/span> <span class=\"n\">local<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">];<\/span>\n            <span class=\"p\">}<\/span>\n        <span class=\"p\">}<\/span>\n\n        <span class=\"k\">return<\/span> <span class=\"n\">sum<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"p\">[<\/span><span class=\"n\">Benchmark<\/span><span class=\"p\">]<\/span>\n    <span class=\"k\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">ArrayListForEach<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>        \n        <span class=\"c1\">\/\/In C#, List&lt;T&gt; is an array backed list<\/span>\n        <span class=\"n\">List<\/span><span class=\"p\">&lt;<\/span><span class=\"kt\">int<\/span><span class=\"p\">&gt;<\/span> <span class=\"n\">local<\/span> <span class=\"p\">=<\/span> <span class=\"n\">arrayList<\/span><span class=\"p\">;<\/span>\n        <span class=\"kt\">int<\/span> <span class=\"n\">sum<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span>\n        <span class=\"k\">checked<\/span>\n        <span class=\"p\">{<\/span>\n            <span class=\"k\">foreach<\/span> <span class=\"p\">(<\/span><span class=\"kt\">var<\/span> <span class=\"n\">x<\/span> <span class=\"k\">in<\/span> <span class=\"n\">local<\/span><span class=\"p\">)<\/span>\n            <span class=\"p\">{<\/span>\n                <span class=\"n\">sum<\/span> <span class=\"p\">+=<\/span> <span class=\"n\">x<\/span><span class=\"p\">;<\/span>\n            <span class=\"p\">}<\/span>\n        <span class=\"p\">}<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">sum<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"p\">[<\/span><span class=\"n\">Benchmark<\/span><span class=\"p\">]<\/span>\n    <span class=\"k\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">RawArrayLinq<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"kt\">int<\/span><span class=\"p\">[]<\/span> <span class=\"n\">local<\/span> <span class=\"p\">=<\/span> <span class=\"n\">rawArray<\/span><span class=\"p\">;<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">local<\/span><span class=\"p\">.<\/span><span class=\"nf\">Sum<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"p\">[<\/span><span class=\"n\">Benchmark<\/span><span class=\"p\">]<\/span>\n    <span class=\"k\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">RawArrayForEach<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"kt\">int<\/span><span class=\"p\">[]<\/span> <span class=\"n\">local<\/span> <span class=\"p\">=<\/span> <span class=\"n\">rawArray<\/span><span class=\"p\">;<\/span>\n        <span class=\"kt\">int<\/span> <span class=\"n\">sum<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span>\n        <span class=\"k\">checked<\/span>\n        <span class=\"p\">{<\/span>\n            <span class=\"k\">foreach<\/span> <span class=\"p\">(<\/span><span class=\"kt\">var<\/span> <span class=\"n\">x<\/span> <span class=\"k\">in<\/span> <span class=\"n\">local<\/span><span class=\"p\">)<\/span>\n            <span class=\"p\">{<\/span>\n                <span class=\"n\">sum<\/span> <span class=\"p\">+=<\/span> <span class=\"n\">x<\/span><span class=\"p\">;<\/span>\n            <span class=\"p\">}<\/span>\n        <span class=\"p\">}<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">sum<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"p\">[<\/span><span class=\"n\">Benchmark<\/span><span class=\"p\">]<\/span>\n    <span class=\"k\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">RawArrayFor<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"kt\">int<\/span><span class=\"p\">[]<\/span> <span class=\"n\">local<\/span> <span class=\"p\">=<\/span> <span class=\"n\">rawArray<\/span><span class=\"p\">;<\/span>\n        <span class=\"kt\">int<\/span> <span class=\"n\">sum<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span>\n\n        <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"p\">&lt;<\/span> <span class=\"n\">local<\/span><span class=\"p\">.<\/span><span class=\"n\">Length<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span><span class=\"p\">++)<\/span>\n        <span class=\"p\">{<\/span>\n            <span class=\"k\">checked<\/span>\n            <span class=\"p\">{<\/span>\n                <span class=\"n\">sum<\/span> <span class=\"p\">+=<\/span> <span class=\"n\">local<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">];<\/span>\n            <span class=\"p\">}<\/span>\n        <span class=\"p\">}<\/span>\n\n        <span class=\"k\">return<\/span> <span class=\"n\">sum<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<script src=\"https:\/\/code.jquery.com\/jquery-2.2.4.min.js\" type=\"text\/javascript\"><\/script>\n\n<script src=\"https:\/\/code.highcharts.com\/highcharts.js\"><\/script>\n\n<script src=\"\/js\/highchartTable-min.js\" type=\"text\/javascript\"><\/script>\n\n<script>\n    $(document).ready(function() {\n        $('table.highchart').highchartTable();\n    });\n<\/script>\n\n","pubDate":"Sat, 20 Aug 2016 19:17:27 +0000","link":"https:\/\/jackmott.github.io\/\/programming\/2016\/08\/20\/when-bigo-foolsya.html","guid":"https:\/\/jackmott.github.io\/\/programming\/2016\/08\/20\/when-bigo-foolsya.html","category":"programming"},{"title":"Adventures in F# Performance","description":"<p>Apologies to functional programming enthusiasts, what follows is a lot of imperative code.  What can I say, it is the \narray library after all!<\/p>\n\n<p>After working on an F# <a href=\"https:\/\/github.com\/jackmott\/SIMDArray\">SIMD Array library<\/a> for a while, and learning about some nice bench \nmarking tools for .NET thanks to <a href=\"https:\/\/twitter.com\/cloudRoutine\">Jared Hester<\/a>. I got the idea to try contributing to the F# core\nlibraries myself.  I had been poking around in the  official <a href=\"https:\/\/github.com\/Microsoft\/visualfsharp\">Microsoft F# repo<\/a> because\nI was modeling my SIMD Library after the <a href=\"https:\/\/github.com\/Microsoft\/visualfsharp\/blob\/master\/src\/fsharp\/FSharp.Core\/array.fs\">core Array library<\/a>, \nduplicating all relevant functions in SIMD form. As I got familiar with the code I saw a function I thought I could speed up. Steffen Forkmann pointed me\nto a <a href=\"http:\/\/www.navision-blog.de\/blog\/2016\/04\/25\/make-failure-great-again-a-small-journey-into-the-f-compiler\/\">blog post of his<\/a> about how to get started \nbuilding and contributing to the FSharp language, so I got to work.<\/p>\n\n<h3 id=\"arrayfilter\">Array.filter<\/h3>\n\n<p>This was the first function I thought I could improve, and mostly I was wrong! <code class=\"highlighter-rouge\">Array.filter<\/code> takes an array and a predicate function as its \narguments and applies the function to each element of the array. The resulting array contains only the elements that satisfy the predicate.\nThe original implementation used a List<T>, which is a .NET collection similar to a C++ Vector, an array backed List that doubles in size as you add items and fill it up.  Each time you\nfill it up, you have to allocate a whole new array and discard the old one.  Which leads to a worst case scenario where if the array's length just exceeds \na power of 2, like 1025, and 0 elements are filtered, you end up allocating 3,836 elements when you only needed 1025. And then you allocate another 1025 \nto copy the array out of the List. But in the best case, you allocate only a handful of bytes for List<T> overhead, when everything is filtered:<\/T><\/T><\/p>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">let<\/span> <span class=\"n\">filter<\/span> <span class=\"n\">f<\/span> <span class=\"p\">(<\/span><span class=\"kt\">array<\/span><span class=\"o\">:<\/span> <span class=\"n\">_<\/span><span class=\"bp\">[]<\/span><span class=\"p\">)<\/span> <span class=\"o\">=<\/span> \n    <span class=\"n\">checkNonNull<\/span> <span class=\"s2\">\"array\"<\/span> <span class=\"kt\">array<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">res<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">List<\/span><span class=\"o\">&lt;_&gt;<\/span><span class=\"bp\">()<\/span> <span class=\"o\">\/\/<\/span> <span class=\"nc\">ResizeArray<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span> <span class=\"k\">to<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span> <span class=\"o\">-<\/span> <span class=\"mi\">1<\/span> <span class=\"k\">do<\/span> \n        <span class=\"k\">let<\/span> <span class=\"n\">x<\/span> <span class=\"o\">=<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span> \n        <span class=\"k\">if<\/span> <span class=\"n\">f<\/span> <span class=\"n\">x<\/span> <span class=\"k\">then<\/span> <span class=\"n\">res<\/span><span class=\"o\">.<\/span><span class=\"nc\">Add<\/span><span class=\"p\">(<\/span><span class=\"n\">x<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">res<\/span><span class=\"o\">.<\/span><span class=\"nc\">ToArray<\/span><span class=\"bp\">()<\/span>\n\n<\/code><\/pre><\/div><\/div>\n\n<p>I tried a few things, and settled on this for a while:<\/p>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">let<\/span> <span class=\"n\">filter<\/span> <span class=\"n\">f<\/span> <span class=\"p\">(<\/span><span class=\"kt\">array<\/span><span class=\"o\">:<\/span> <span class=\"n\">_<\/span><span class=\"bp\">[]<\/span><span class=\"p\">)<\/span> <span class=\"o\">=<\/span> \n    <span class=\"n\">checkNonNull<\/span> <span class=\"s2\">\"array\"<\/span> <span class=\"kt\">array<\/span>                        \n    <span class=\"k\">let<\/span> <span class=\"n\">temp<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">zeroCreateUnchecked<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span>\n    <span class=\"k\">let<\/span> <span class=\"k\">mutable<\/span> <span class=\"n\">c<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span> <span class=\"k\">to<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span> <span class=\"k\">do<\/span>                \n        <span class=\"k\">if<\/span> <span class=\"n\">f<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span> <span class=\"k\">then<\/span>\n            <span class=\"n\">temp<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"bp\">true<\/span>\n            <span class=\"n\">c<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"n\">c<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\n            \n    <span class=\"k\">let<\/span> <span class=\"n\">result<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">zeroCreateUnchecked<\/span> <span class=\"n\">c<\/span>\n    <span class=\"n\">c<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"mi\">0<\/span>    \n    <span class=\"k\">let<\/span> <span class=\"k\">mutable<\/span> <span class=\"n\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n    <span class=\"k\">while<\/span> <span class=\"n\">c<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">result<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span> <span class=\"k\">do<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">temp<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span> <span class=\"k\">then<\/span>\n            <span class=\"n\">result<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">c<\/span><span class=\"p\">]<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span>\n            <span class=\"n\">c<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"n\">c<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\n        <span class=\"n\">i<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"n\">i<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\n    <span class=\"n\">result<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>This allocates an array of booleans the same length as the input up front, which are usually stored as bytes in .NET.  So in the common case, where\nyou have a 32bit or 64bit pointer, int, or float, as your array element, it will allocate no more than 1\/8 to 1\/4 of your array size in extra\ndata instead of 3x to 4x. Reducing GC pressure is a big win with garbage collected languages so that seemed like a good thing. There are some gotchas\nthough:<\/p>\n\n<ul>\n  <li>The loops now both have branches in them.<\/li>\n  <li>The branch pattern will sometimes be random, so branch prediction will miss them, which is slow.<\/li>\n  <li>The performance advantage goes negative compared to the original implementation as the size of the array type shrinks.<\/li>\n<\/ul>\n\n<p>So in cases where most things are filtered, and the distribution of elements is somewhat random as to whether they get filtered or not, \nperformance was sometimes worse.  Performance also differed in 32bit vs 64 bit builds, and on different machines.  Benchmarking this was \nreally hard because you have to account for different array type sizes, lengths, different distribution of filtering and amount of filtering. It didn\u2019t always win, and it was hard to decide if it was really better.<\/p>\n\n<p>Then <a href=\"https:\/\/github.com\/asik\">Asik<\/a> suggested a solution which ended up being the final answer:<\/p>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">let<\/span> <span class=\"n\">filter<\/span> <span class=\"n\">f<\/span> <span class=\"p\">(<\/span><span class=\"kt\">array<\/span><span class=\"o\">:<\/span> <span class=\"n\">_<\/span><span class=\"bp\">[]<\/span><span class=\"p\">)<\/span> <span class=\"o\">=<\/span> \n    <span class=\"n\">checkNonNull<\/span> <span class=\"s2\">\"array\"<\/span> <span class=\"kt\">array<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">res<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">zeroCreateUnchecked<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span> \n    <span class=\"k\">let<\/span> <span class=\"k\">mutable<\/span> <span class=\"n\">count<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">x<\/span> <span class=\"k\">in<\/span> <span class=\"kt\">array<\/span> <span class=\"k\">do<\/span>                 \n        <span class=\"k\">if<\/span> <span class=\"n\">f<\/span> <span class=\"n\">x<\/span> <span class=\"k\">then<\/span> \n            <span class=\"n\">res<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">count<\/span><span class=\"p\">]<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"n\">x<\/span>\n            <span class=\"n\">count<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"n\">count<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\n    <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">subUnchecked<\/span> <span class=\"mi\">0<\/span> <span class=\"n\">count<\/span> <span class=\"n\">res<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>This just allocates an entire array of whatever type was input, adds elements into it, and then uses Array.sub which calls fast native code to copy\nsub sections of arrays into new ones.  This was <em>always<\/em> faster than the original core lib solution, but sometimes allocated more memory.  The \nMicrosoft guys considered that a net win, so they took it. The improvement here varied a lot, but was usually around 20% faster.  Worst case performance \nwould be with large array types (Like a 16 byte struct) where most elements are likely to get filtered.  You might want to roll your own filter if you are doing\nthat.  This same optimization was applied to the similar Array.choose function.<\/p>\n\n<h4 id=\"update\">UPDATE:<\/h4>\n\n<p><a href=\"https:\/\/github.com\/asik\">Asik<\/a> and I have collaborated and got a <a href=\"https:\/\/github.com\/jackmott\/visualfsharp\/blob\/497f11a9bc7367af79264090096d3bf6da2b6903\/src\/fsharp\/FSharp.Core\/array.fs#L487\">new filter merged<\/a>\n that keeps the speed of the above solution, while reducing allocations by ~30% on average. We did this by implementing a growing array by hand, taking advantage of extra knowledge we have, like\n that the upper bound for it\u2019s size is array.Length, and some other tricks.  Another <a href=\"https:\/\/gist.github.com\/manofstick\/229384a1bd0bdb26caf9a780b952d9b8#file-filter_bench-fs-L89\">interesting solution<\/a> is being proposed by\n <a href=\"https:\/\/gist.github.com\/manofstick\">Paul Westcott<\/a> which uses a bit array. This may reduce allocations yet again while maintaining similar rerformance, pretty cool.<\/p>\n\n<p>As an aside, if your predicate is a pure function, and a fast function, you can <a href=\"https:\/\/github.com\/jackmott\/SIMDArray\/blob\/master\/src\/SIMDArray\/SIMDArray.fs#L1076\">apply the predicate twice<\/a>\nto avoid any extra allocations at all. This is <em>very<\/em> fast for sufficiently simple predicates, like &gt; or &lt; comparisons.<\/p>\n\n<h4 id=\"performance-test-results-for-filtering-50-of-random-doubles-on-64bit-ryujit\">Performance test results for filtering 50% of random doubles on 64bit RyuJit<\/h4>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Median<\/th>\n      <th>StdDev<\/th>\n      <th>Gen 0<\/th>\n      <th>Gen 1<\/th>\n      <th>Gen 2<\/th>\n      <th>Bytes Allocated\/Op<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>CoreFilter<\/td>\n      <td>10.7906 ms<\/td>\n      <td>0.2096 ms<\/td>\n      <td>20.00<\/td>\n      <td>-<\/td>\n      <td>314.00<\/td>\n      <td>3 953 196,34<\/td>\n    <\/tr>\n    <tr>\n      <td>ArrayFilter<\/td>\n      <td>8.3605 ms<\/td>\n      <td>0.0374 ms<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>329.99<\/td>\n      <td>3 762 296,97<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<h3 id=\"arraypartition\">Array.partition<\/h3>\n\n<p>I wasn\u2019t too happy with the filter optimization because I felt like someimtes taking a memory hit wasn\u2019t so great. So I started scanning through the library for\nother opportunities, and came across Array.partition, which takes an array and a predicate, returning a tuple with two arrays. One array contains every element \nthat was true, the other every element that was false.<\/p>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">let<\/span> <span class=\"n\">partition<\/span> <span class=\"n\">f<\/span> <span class=\"p\">(<\/span><span class=\"kt\">array<\/span><span class=\"o\">:<\/span> <span class=\"n\">_<\/span><span class=\"bp\">[]<\/span><span class=\"p\">)<\/span> <span class=\"o\">=<\/span> \n    <span class=\"n\">checkNonNull<\/span> <span class=\"s2\">\"array\"<\/span> <span class=\"kt\">array<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">res1<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">List<\/span><span class=\"o\">&lt;_&gt;<\/span><span class=\"bp\">()<\/span> <span class=\"o\">\/\/<\/span> <span class=\"nc\">ResizeArray<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">res2<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">List<\/span><span class=\"o\">&lt;_&gt;<\/span><span class=\"bp\">()<\/span> <span class=\"o\">\/\/<\/span> <span class=\"nc\">ResizeArray<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span> <span class=\"k\">to<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span> <span class=\"o\">-<\/span> <span class=\"mi\">1<\/span> <span class=\"k\">do<\/span> \n        <span class=\"k\">let<\/span> <span class=\"n\">x<\/span> <span class=\"o\">=<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span> \n        <span class=\"k\">if<\/span> <span class=\"n\">f<\/span> <span class=\"n\">x<\/span> <span class=\"k\">then<\/span> <span class=\"n\">res1<\/span><span class=\"o\">.<\/span><span class=\"nc\">Add<\/span><span class=\"p\">(<\/span><span class=\"n\">x<\/span><span class=\"p\">)<\/span> <span class=\"k\">else<\/span> <span class=\"n\">res2<\/span><span class=\"o\">.<\/span><span class=\"nc\">Add<\/span><span class=\"p\">(<\/span><span class=\"n\">x<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">res1<\/span><span class=\"o\">.<\/span><span class=\"nc\">ToArray<\/span><span class=\"bp\">()<\/span><span class=\"o\">,<\/span> <span class=\"n\">res2<\/span><span class=\"o\">.<\/span><span class=\"nc\">ToArray<\/span><span class=\"bp\">()<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>I had more respect for the (array backed) List solutions now, after failing to get a clear win by using raw arrays with filter. So I tried to look for \nsomething more clever. I realized that one invariant here is that the result will always be the same size as the input.  If the input is 100 elements,\nthe output will be 100 elements.  So fundamentally, we shouldn\u2019t  need to use a data structures that grows. I thought about creating a struct where\nyou could tag each element with a true or false on the first pass, and then copy the results into the two output arrays. But that still wastes\narray.Length bytes of memory.  Then I had a great idea, maybe my best idea!  Allocate an array the same size and type as the input, and put all the true \nelements on the left, and all the false elements on the right! The only memory wasted is an extra int to keep track of where one set ends and the\nother begins.  You then just copy the left side of the array into the first result, and the reverse of the right side of the array into the second result:<\/p>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">let<\/span> <span class=\"n\">partition<\/span> <span class=\"n\">f<\/span> <span class=\"p\">(<\/span><span class=\"kt\">array<\/span><span class=\"o\">:<\/span> <span class=\"n\">_<\/span><span class=\"bp\">[]<\/span><span class=\"p\">)<\/span> <span class=\"o\">=<\/span> \n    <span class=\"n\">checkNonNull<\/span> <span class=\"s2\">\"array\"<\/span> <span class=\"kt\">array<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">res<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">zeroCreateUnchecked<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span>        \n    <span class=\"k\">let<\/span> <span class=\"k\">mutable<\/span> <span class=\"n\">upCount<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n    <span class=\"k\">let<\/span> <span class=\"k\">mutable<\/span> <span class=\"n\">downCount<\/span> <span class=\"o\">=<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span>    \n    <span class=\"k\">for<\/span> <span class=\"n\">x<\/span> <span class=\"k\">in<\/span> <span class=\"kt\">array<\/span> <span class=\"k\">do<\/span>                \n        <span class=\"k\">if<\/span> <span class=\"n\">f<\/span> <span class=\"n\">x<\/span> <span class=\"k\">then<\/span> \n            <span class=\"n\">res<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">upCount<\/span><span class=\"p\">]<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"n\">x<\/span>\n            <span class=\"n\">upCount<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"n\">upCount<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\n        <span class=\"k\">else<\/span>\n            <span class=\"n\">res<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">downCount<\/span><span class=\"p\">]<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"n\">x<\/span>\n            <span class=\"n\">downCount<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"n\">downCount<\/span> <span class=\"o\">-<\/span> <span class=\"mi\">1<\/span>\n        \n    <span class=\"k\">let<\/span> <span class=\"n\">res1<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">subUnchecked<\/span> <span class=\"mi\">0<\/span> <span class=\"n\">upCount<\/span> <span class=\"n\">res<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">res2<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">zeroCreateUnchecked<\/span> <span class=\"p\">(<\/span><span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span> <span class=\"o\">-<\/span> <span class=\"n\">upCount<\/span><span class=\"p\">)<\/span>    \n\n    <span class=\"n\">downCount<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span> <span class=\"k\">to<\/span> <span class=\"n\">res2<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span> <span class=\"k\">do<\/span>\n        <span class=\"n\">res2<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"n\">res<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">downCount<\/span><span class=\"p\">]<\/span>        \n        <span class=\"n\">downCount<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"n\">downCount<\/span> <span class=\"o\">-<\/span> <span class=\"mi\">1<\/span>\n\n    <span class=\"n\">res1<\/span> <span class=\"o\">,<\/span> <span class=\"n\">res2<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h4 id=\"performance-test-results-for-partitioning-random-int-arrays-with-predicate-fun-x---x--2--0\">Performance test results for partitioning random int arrays with predicate <code class=\"highlighter-rouge\">(fun x -&gt; x % 2 = 0)<\/code><\/h4>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>ArrayLength<\/th>\n      <th>Median<\/th>\n      <th>StdDev<\/th>\n      <th>Scaled<\/th>\n      <th>Gen 0<\/th>\n      <th>Gen 1<\/th>\n      <th>Gen 2<\/th>\n      <th>Bytes Allocated\/Op<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>Partition<\/td>\n      <td>10<\/td>\n      <td>180.8758 ns<\/td>\n      <td>16.3650 ns<\/td>\n      <td>1.00<\/td>\n      <td>0.01<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>185.22<\/td>\n    <\/tr>\n    <tr>\n      <td>NewPartition<\/td>\n      <td>10<\/td>\n      <td>76.6145 ns<\/td>\n      <td>1.2114 ns<\/td>\n      <td>0.42<\/td>\n      <td>0.01<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>90.38<\/td>\n    <\/tr>\n    <tr>\n      <td>Partition<\/td>\n      <td>10000<\/td>\n      <td>117,268.5175 ns<\/td>\n      <td>1,064.2667 ns<\/td>\n      <td>1.00<\/td>\n      <td>6.40<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>99,742.26<\/td>\n    <\/tr>\n    <tr>\n      <td>NewPartition<\/td>\n      <td>10000<\/td>\n      <td>79,020.6291 ns<\/td>\n      <td>474.4149 ns<\/td>\n      <td>0.67<\/td>\n      <td>2.64<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>43,572.00<\/td>\n    <\/tr>\n    <tr>\n      <td>Partition<\/td>\n      <td>10000000<\/td>\n      <td>154,545,402.8213 ns<\/td>\n      <td>3,116,253.3692 ns<\/td>\n      <td>1.00<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>62.02<\/td>\n      <td>59,133,643.66<\/td>\n    <\/tr>\n    <tr>\n      <td>NewPartition<\/td>\n      <td>10000000<\/td>\n      <td>98,768,489.7225 ns<\/td>\n      <td>726,198.4079 ns<\/td>\n      <td>0.64<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>34.00<\/td>\n      <td>29,686,956.03<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<h3 id=\"adventures-in-il-and-dissasembly\">Adventures in IL and Dissasembly<\/h3>\n\n<p>One of the performance drawbacks of most managed\/safe languages is that they do array bounds checking.  This prevents you from accidentally wandering off the end\nof an array and over writing memory at random, which is a useful feature.  But it comes with a performance cost, as you end up eating some cpu cycles checking array \nbounds each time through the loop.  The .NET JIT will identify <a href=\"https:\/\/blogs.msdn.microsoft.com\/clrcodegeneration\/2009\/08\/13\/array-bounds-check-elimination-in-the-clr\/\">Some but not all<\/a> \ncases when these bounds checks can be eliminated.  You have to take some care to structure your loop just right, or it will be missed.  F# added some confusion\nhere since their loops have different syntax than C#, and <a href=\"https:\/\/github.com\/Microsoft\/visualfsharp\/issues\/1419\">sometimes compile strangely, or badly<\/a>. \nYou can peek at the byte code or C# equivalent representation of it with tools like <a href=\"http:\/\/ilspy.net\/\">ILSpy<\/a>\nFor instance this loop:<\/p>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">let<\/span> <span class=\"n\">len<\/span> <span class=\"o\">=<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span>\n<span class=\"k\">for<\/span> <span class=\"n\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span> <span class=\"k\">to<\/span> <span class=\"n\">len<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span> <span class=\"k\">do<\/span>\n  <span class=\"c\">(* stuff *)<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>compiles to the C# equivalent of:<\/p>\n\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kt\">int<\/span> <span class=\"n\">num<\/span> <span class=\"p\">=<\/span> <span class=\"n\">len<\/span> <span class=\"p\">-<\/span> <span class=\"m\">1<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"n\">num<\/span> <span class=\"p\">&gt;=<\/span> <span class=\"n\">i<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">do<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/ stuff<\/span>\n        <span class=\"n\">i<\/span><span class=\"p\">++;<\/span>\n    <span class=\"p\">}<\/span>\n    <span class=\"k\">while<\/span> <span class=\"p\">(<\/span><span class=\"n\">i<\/span> <span class=\"p\">!=<\/span> <span class=\"n\">num<\/span> <span class=\"p\">+<\/span> <span class=\"m\">1<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n\n<\/code><\/pre><\/div><\/div>\n\n<p>This is madness, maybe some of that madness gets JITted away, but it definitely does cause the array bounds elision to be missed, slowing it down.\nThis was a pattern used in many places in the core Array library, so I just went through and mechanistically replaced them all with the pattern that works:<\/p>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">for<\/span> <span class=\"n\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span> <span class=\"k\">to<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span> <span class=\"k\">do<\/span>\n    <span class=\"c\">(* stuff *)<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Which becomes the C# equivalent of:<\/p>\n\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"p\">&lt;<\/span> <span class=\"n\">array<\/span><span class=\"p\">.<\/span><span class=\"n\">Length<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span><span class=\"p\">++)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/stuff<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>AHHHH, much better, and now we get array bounds elision from the JIT too.  The impact of this change can be pretty big in some cases,\nwhen any functions applied per array element are very simple the array bounds checking makes up a sizeable % of total run time.  In other cases\nit will be a very small impact. Array.map (fun x-&gt; SieveofEratosthenes x) isn\u2019t going to be noticeably better. But it impacted almost all of the \nfunctions in the Array module, and I assume (which is dangerous) it would take some overhead out of JITing the IL as well.<\/p>\n\n<p>If you want to know for sure if the loop is doing what you want, as 32Bit JITs differ from the 64 bit one differ from Mono etc., you will need to view the dissasembly. In\nVisual Studio you can get it at from Debug -&gt; Windows -&gt; Disassembly while the program is running.  Here is an example of code with, and without a bounds check:<\/p>\n\n<p><img src=\"\/images\/dissassembly.png\" alt=\"Dissasembly Example\" \/><\/p>\n\n<p>Since this process is done in the JIT, you don\u2019t always have control over it. Sometimes you can massage your code to be sure the JIT will do the right thing,\nbut sometimes you can\u2019t.  If you get desperate, write the function in C# using an unsafe loop, and call it from F#.<\/p>\n\n<h4 id=\"other-loop-patterns-to-beware-of-in-net\">Other loop patterns to beware of in .NET:<\/h4>\n\n<ul>\n  <li>For lops that go from 0 to anything <em>less<\/em> than the array length, will not get the bounds check elided.<\/li>\n  <li>For loops that go backwards, will not get array bounds checking elided.<\/li>\n  <li>With for loops over arrays in F# that have a stride length of something other than 1, the compiler generates a loop that uses an Enumerator, which is much slower and generates garbage. Use a while loop, or tail recursion instead.<\/li>\n  <li>For loops over arrays that are class members will miss the array bounds elision. Make a function local copy of the array reference first.<\/li>\n  <li>The <code class=\"highlighter-rouge\">for x in array<\/code> syntax in F# works out fine. There may be other performance considerations but a normal for loop is generated and bounds checking is elided.<\/li>\n<\/ul>\n\n<p><em>These things are all true as of 64bit RyuJIT .NET 4.6.2 and F# 4.4.0, some of them are being actively worked on and could improve soon.<\/em><\/p>\n\n<h4 id=\"performance-test-results-of-bounds--check-elision-from-arraymap-with-mapping-function-fun-x---x--1\">Performance test results of bounds  check elision from <code class=\"highlighter-rouge\">Array.map<\/code> with mapping function <code class=\"highlighter-rouge\">(fun x -&gt; x + 1)<\/code><\/h4>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Length<\/th>\n      <th>Median<\/th>\n      <th>StdDev<\/th>\n      <th>Scaled<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>Old<\/td>\n      <td>10<\/td>\n      <td>17.5030 ns<\/td>\n      <td>0.5275 ns<\/td>\n      <td>1.00<\/td>\n    <\/tr>\n    <tr>\n      <td>New<\/td>\n      <td>10<\/td>\n      <td>14.1205 ns<\/td>\n      <td>0.4858 ns<\/td>\n      <td>0.81<\/td>\n    <\/tr>\n    <tr>\n      <td>Old<\/td>\n      <td>10000<\/td>\n      <td>10,212.8762 ns<\/td>\n      <td>118.7990 ns<\/td>\n      <td>1.00<\/td>\n    <\/tr>\n    <tr>\n      <td>New<\/td>\n      <td>10000<\/td>\n      <td>8,963.2690 ns<\/td>\n      <td>329.8907 ns<\/td>\n      <td>0.88<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<h3 id=\"delving-into-parallel\">Delving Into Parallel<\/h3>\n\n<p>The Array module has a sub module Parallel.  <code class=\"highlighter-rouge\">Array.Parallel.map<\/code>, for instance, will use a <code class=\"highlighter-rouge\">Parallel.For<\/code> loop to multithread your map operation.  Scanning through these\nI saw <code class=\"highlighter-rouge\">Parallel.partition<\/code>:<\/p>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">let<\/span> <span class=\"n\">partition<\/span> <span class=\"n\">predicate<\/span> <span class=\"p\">(<\/span><span class=\"kt\">array<\/span> <span class=\"o\">:<\/span> <span class=\"k\">'<\/span><span class=\"nc\">T<\/span><span class=\"bp\">[]<\/span><span class=\"p\">)<\/span> <span class=\"o\">=<\/span>\n    <span class=\"n\">checkNonNull<\/span> <span class=\"s2\">\"array\"<\/span> <span class=\"kt\">array<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">inputLength<\/span> <span class=\"o\">=<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">lastInputIndex<\/span> <span class=\"o\">=<\/span> <span class=\"n\">inputLength<\/span> <span class=\"o\">-<\/span> <span class=\"mi\">1<\/span>\n\n    <span class=\"k\">let<\/span> <span class=\"n\">isTrue<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">zeroCreateUnchecked<\/span> <span class=\"n\">inputLength<\/span>\n    <span class=\"nn\">Parallel<\/span><span class=\"p\">.<\/span><span class=\"nc\">For<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"o\">,<\/span> <span class=\"n\">inputLength<\/span><span class=\"o\">,<\/span> \n        <span class=\"k\">fun<\/span> <span class=\"n\">i<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">isTrue<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"n\">predicate<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span>\n        <span class=\"p\">)<\/span> <span class=\"o\">|&gt;<\/span> <span class=\"n\">ignore<\/span>\n    \n    <span class=\"k\">let<\/span> <span class=\"k\">mutable<\/span> <span class=\"bp\">true<\/span><span class=\"nc\">Length<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">i<\/span> <span class=\"k\">in<\/span> <span class=\"mi\">0<\/span> <span class=\"o\">..<\/span> <span class=\"n\">lastInputIndex<\/span> <span class=\"k\">do<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">isTrue<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span> <span class=\"k\">then<\/span> <span class=\"bp\">true<\/span><span class=\"nc\">Length<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"bp\">true<\/span><span class=\"nc\">Length<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\n    \n    <span class=\"k\">let<\/span> <span class=\"bp\">true<\/span><span class=\"nc\">Result<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">zeroCreateUnchecked<\/span> <span class=\"bp\">true<\/span><span class=\"nc\">Length<\/span>\n    <span class=\"k\">let<\/span> <span class=\"bp\">false<\/span><span class=\"nc\">Result<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">zeroCreateUnchecked<\/span> <span class=\"p\">(<\/span><span class=\"n\">inputLength<\/span> <span class=\"o\">-<\/span> <span class=\"bp\">true<\/span><span class=\"nc\">Length<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">let<\/span> <span class=\"k\">mutable<\/span> <span class=\"n\">iTrue<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n    <span class=\"k\">let<\/span> <span class=\"k\">mutable<\/span> <span class=\"n\">iFalse<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span> <span class=\"k\">to<\/span> <span class=\"n\">lastInputIndex<\/span> <span class=\"k\">do<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">isTrue<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span> <span class=\"k\">then<\/span>\n            <span class=\"bp\">true<\/span><span class=\"nn\">Result<\/span><span class=\"p\">.[<\/span><span class=\"n\">iTrue<\/span><span class=\"p\">]<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span>\n            <span class=\"n\">iTrue<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"n\">iTrue<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\n        <span class=\"k\">else<\/span>\n            <span class=\"bp\">false<\/span><span class=\"nn\">Result<\/span><span class=\"p\">.[<\/span><span class=\"n\">iFalse<\/span><span class=\"p\">]<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span>\n            <span class=\"n\">iFalse<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"n\">iFalse<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\n\n    <span class=\"p\">(<\/span><span class=\"bp\">true<\/span><span class=\"nc\">Result<\/span><span class=\"o\">,<\/span> <span class=\"bp\">false<\/span><span class=\"nc\">Result<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>What stuck out at me here was that they were iterating over the entire isTrue array a second time in order to count up how many true elements \nthere are. This struck me as fundamentally unnecessary.  So I tried creating an accumulation variable above the Parallel.For call, and just incrementing \nthat within the loop. Nope! You can\u2019t add in parallel like that safely on x86 (or perhaps any architecture?) It worked sometimes but not always.  Then I remembered<br \/>\n<code class=\"highlighter-rouge\">System.Threading.Interlocked.Increment(Int32)<\/code>, which provides a thread safe way to increment an int.  This worked! But then it was just as slow as the\nscalar version of the function, since every thread was constantly locking on the increment function. So I \n<a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/system.threading.tasks.parallel.for(v=vs.110).aspx\">read the documentation<\/a>. Sometimes this stuff is awful to\nread.  <code class=\"highlighter-rouge\">Func&lt;Int32&gt;<\/code>? <code class=\"highlighter-rouge\">Action&lt;TLocal&gt;<\/code>? PC LOAD LETTER?!?!  But if you go slow and stare at this for a while it will start to make sense.  The key info here\nis that there is a <code class=\"highlighter-rouge\">Parallel.For<\/code> loop which can internally keep track of an accumulator for you.  This will let us track the total number of true\nelements without iterating over the array again.  So the new solution becomes:<\/p>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">let<\/span> <span class=\"n\">partition<\/span> <span class=\"n\">predicate<\/span> <span class=\"p\">(<\/span><span class=\"kt\">array<\/span> <span class=\"o\">:<\/span> <span class=\"k\">'<\/span><span class=\"nc\">T<\/span><span class=\"bp\">[]<\/span><span class=\"p\">)<\/span> <span class=\"o\">=<\/span>\n    <span class=\"n\">checkNonNull<\/span> <span class=\"s2\">\"array\"<\/span> <span class=\"kt\">array<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">inputLength<\/span> <span class=\"o\">=<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span>                \n    <span class=\"k\">let<\/span> <span class=\"n\">isTrue<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">zeroCreateUnchecked<\/span> <span class=\"n\">inputLength<\/span>                \n    <span class=\"k\">let<\/span> <span class=\"k\">mutable<\/span> <span class=\"bp\">true<\/span><span class=\"nc\">Length<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n                                    \n    <span class=\"nn\">Parallel<\/span><span class=\"p\">.<\/span><span class=\"nc\">For<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"o\">,<\/span> \n                    <span class=\"n\">inputLength<\/span><span class=\"o\">,<\/span> \n                    <span class=\"p\">(<\/span><span class=\"k\">fun<\/span> <span class=\"bp\">()<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span><span class=\"o\">,<\/span>\n                    <span class=\"p\">(<\/span><span class=\"k\">fun<\/span> <span class=\"n\">i<\/span> <span class=\"n\">_<\/span> <span class=\"bp\">true<\/span><span class=\"nc\">Count<\/span> <span class=\"o\">-&gt;<\/span> \n                    <span class=\"k\">if<\/span> <span class=\"n\">predicate<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span> <span class=\"k\">then<\/span>\n                        <span class=\"n\">isTrue<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"bp\">true<\/span>\n                        <span class=\"bp\">true<\/span><span class=\"nc\">Count<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\n                    <span class=\"k\">else<\/span>\n                        <span class=\"bp\">true<\/span><span class=\"nc\">Count<\/span><span class=\"p\">)<\/span><span class=\"o\">,<\/span>                        \n                    <span class=\"nc\">Action<\/span><span class=\"o\">&lt;<\/span><span class=\"kt\">int<\/span><span class=\"o\">&gt;<\/span> <span class=\"p\">(<\/span><span class=\"k\">fun<\/span> <span class=\"n\">x<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nn\">System<\/span><span class=\"p\">.<\/span><span class=\"nn\">Threading<\/span><span class=\"p\">.<\/span><span class=\"nn\">Interlocked<\/span><span class=\"p\">.<\/span><span class=\"nc\">Add<\/span><span class=\"p\">(<\/span><span class=\"o\">&amp;<\/span><span class=\"bp\">true<\/span><span class=\"nc\">Length<\/span><span class=\"o\">,<\/span><span class=\"n\">x<\/span><span class=\"p\">)<\/span> <span class=\"o\">|&gt;<\/span> <span class=\"n\">ignore<\/span><span class=\"p\">)<\/span> <span class=\"p\">)<\/span> <span class=\"o\">|&gt;<\/span> <span class=\"n\">ignore<\/span>\n                    \n    <span class=\"k\">let<\/span> <span class=\"n\">res1<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">zeroCreateUnchecked<\/span> <span class=\"bp\">true<\/span><span class=\"nc\">Length<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">res2<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">zeroCreateUnchecked<\/span> <span class=\"p\">(<\/span><span class=\"n\">inputLength<\/span> <span class=\"o\">-<\/span> <span class=\"bp\">true<\/span><span class=\"nc\">Length<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">let<\/span> <span class=\"k\">mutable<\/span> <span class=\"n\">iTrue<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n    <span class=\"k\">let<\/span> <span class=\"k\">mutable<\/span> <span class=\"n\">iFalse<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span> <span class=\"k\">to<\/span> <span class=\"n\">isTrue<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span> <span class=\"k\">do<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">isTrue<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span> <span class=\"k\">then<\/span>\n            <span class=\"n\">res1<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">iTrue<\/span><span class=\"p\">]<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span>\n            <span class=\"n\">iTrue<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"n\">iTrue<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\n        <span class=\"k\">else<\/span>\n            <span class=\"n\">res2<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">iFalse<\/span><span class=\"p\">]<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"kt\">array<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span>\n            <span class=\"n\">iFalse<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"n\">iFalse<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\n\n    <span class=\"n\">res1<\/span><span class=\"o\">,<\/span> <span class=\"n\">res2<\/span>\n\n<\/code><\/pre><\/div><\/div>\n\n<p>In this case, each thread has its\u2019 own accumulator value, keeping track of their own <code class=\"highlighter-rouge\">trueCount<\/code>. So they are free to increment it without locking.\nAs threads finish, they then do a locked add, adding their own personal <code class=\"highlighter-rouge\">trueCount<\/code> to the final result stored in <code class=\"highlighter-rouge\">trueLength<\/code>.  This locked add only happens \nNumThreads times, instead of array.Length times, so causes no terrible performance penalty. The final result is about 30% faster with no memory use penalty.<\/p>\n\n<h4 id=\"performance-test-results-of-arrayparallelpartition-with-predicate-fun-x---x--2--0\">Performance test results of <code class=\"highlighter-rouge\">Array.Parallel.partition<\/code> with predicate <code class=\"highlighter-rouge\">(fun x -&gt; x % 2 = 0)<\/code><\/h4>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Length<\/th>\n      <th>Median<\/th>\n      <th>StdDev<\/th>\n      <th>Scaled<\/th>\n      <th>Gen 0<\/th>\n      <th>Gen 1<\/th>\n      <th>Gen 2<\/th>\n      <th>Bytes Allocated\/Op<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>Original<\/td>\n      <td>1000<\/td>\n      <td>21.8514 us<\/td>\n      <td>0.5300 us<\/td>\n      <td>1.00<\/td>\n      <td>0.16<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>3,471.77<\/td>\n    <\/tr>\n    <tr>\n      <td>New<\/td>\n      <td>1000<\/td>\n      <td>20.5297 us<\/td>\n      <td>0.8840 us<\/td>\n      <td>0.94<\/td>\n      <td>0.17<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>3,489.75<\/td>\n    <\/tr>\n    <tr>\n      <td>Original<\/td>\n      <td>10000<\/td>\n      <td>160.0466 us<\/td>\n      <td>3.1249 us<\/td>\n      <td>1.00<\/td>\n      <td>1.21<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>28,955.03<\/td>\n    <\/tr>\n    <tr>\n      <td>New<\/td>\n      <td>10000<\/td>\n      <td>118.1885 us<\/td>\n      <td>2.8572 us<\/td>\n      <td>0.74<\/td>\n      <td>1.20<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>28,666.02<\/td>\n    <\/tr>\n    <tr>\n      <td>Original<\/td>\n      <td>100000<\/td>\n      <td>1,282.9827 us<\/td>\n      <td>7.3705 us<\/td>\n      <td>1.00<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>10.17<\/td>\n      <td>211,334.08<\/td>\n    <\/tr>\n    <tr>\n      <td>New<\/td>\n      <td>100000<\/td>\n      <td>917.0063 us<\/td>\n      <td>17.4501 us<\/td>\n      <td>0.71<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>7.27<\/td>\n      <td>151,441.53<\/td>\n    <\/tr>\n    <tr>\n      <td>Original<\/td>\n      <td>1000000<\/td>\n      <td>12,467.9427 us<\/td>\n      <td>728.8799 us<\/td>\n      <td>1.00<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>65.99<\/td>\n      <td>2,353,833.73<\/td>\n    <\/tr>\n    <tr>\n      <td>New<\/td>\n      <td>1000000<\/td>\n      <td>9,700.7108 us<\/td>\n      <td>990.4339 us<\/td>\n      <td>0.78<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>65.24<\/td>\n      <td>2,309,151.64<\/td>\n    <\/tr>\n    <tr>\n      <td>Original<\/td>\n      <td>10000000<\/td>\n      <td>125,043.1745 us<\/td>\n      <td>1,753.3497 us<\/td>\n      <td>1.00<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>35.28<\/td>\n      <td>29,670,713.02<\/td>\n    <\/tr>\n    <tr>\n      <td>New<\/td>\n      <td>10000000<\/td>\n      <td>86,908.7271 us<\/td>\n      <td>1,472.4448 us<\/td>\n      <td>0.70<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>35.53<\/td>\n      <td>29,909,345.33<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p><br \/><\/p>\n\n<h3 id=\"recursion-is-slower--sometimes\">Recursion is slower \u2026 sometimes<\/h3>\n\n<p>Sometimes a recursive implementation will be a substantive speed hit.  While the F# compiler is very good at tail recursion optimization, turning most recursive functions into nice loops, there can still be a small to medium performance penalty in some cases.  For example, Array.compareWith got about 20% faster when converted from this recursive implementation to while loops:<\/p>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code> <span class=\"k\">let<\/span> <span class=\"n\">inline<\/span> <span class=\"n\">compareWith<\/span> <span class=\"p\">(<\/span><span class=\"n\">comparer<\/span><span class=\"o\">:<\/span><span class=\"k\">'<\/span><span class=\"nc\">T<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"k\">'<\/span><span class=\"nc\">T<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"kt\">int<\/span><span class=\"p\">)<\/span> <span class=\"p\">(<\/span><span class=\"n\">array1<\/span><span class=\"o\">:<\/span> <span class=\"k\">'<\/span><span class=\"nc\">T<\/span><span class=\"bp\">[]<\/span><span class=\"p\">)<\/span> <span class=\"p\">(<\/span><span class=\"n\">array2<\/span><span class=\"o\">:<\/span> <span class=\"k\">'<\/span><span class=\"nc\">T<\/span><span class=\"bp\">[]<\/span><span class=\"p\">)<\/span> <span class=\"o\">=<\/span> \n    <span class=\"n\">checkNonNull<\/span> <span class=\"s2\">\"array1\"<\/span> <span class=\"n\">array1<\/span>\n    <span class=\"n\">checkNonNull<\/span> <span class=\"s2\">\"array2\"<\/span> <span class=\"n\">array2<\/span>\n\n    <span class=\"k\">let<\/span> <span class=\"n\">length1<\/span> <span class=\"o\">=<\/span> <span class=\"n\">array1<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">length2<\/span> <span class=\"o\">=<\/span> <span class=\"n\">array2<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span>\n    <span class=\"k\">let<\/span> <span class=\"n\">minLength<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Operators<\/span><span class=\"p\">.<\/span><span class=\"n\">min<\/span> <span class=\"n\">length1<\/span> <span class=\"n\">length2<\/span>\n\n    <span class=\"k\">let<\/span> <span class=\"k\">rec<\/span> <span class=\"n\">loop<\/span> <span class=\"n\">index<\/span>  <span class=\"o\">=<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">index<\/span> <span class=\"o\">=<\/span> <span class=\"n\">minLength<\/span>  <span class=\"k\">then<\/span>\n            <span class=\"k\">if<\/span> <span class=\"n\">length1<\/span> <span class=\"o\">=<\/span> <span class=\"n\">length2<\/span> <span class=\"k\">then<\/span> <span class=\"mi\">0<\/span>\n            <span class=\"n\">elif<\/span> <span class=\"n\">length1<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">length2<\/span> <span class=\"k\">then<\/span> <span class=\"o\">-<\/span><span class=\"mi\">1<\/span>\n            <span class=\"k\">else<\/span> <span class=\"mi\">1<\/span>\n        <span class=\"k\">else<\/span>  \n            <span class=\"k\">let<\/span> <span class=\"n\">result<\/span> <span class=\"o\">=<\/span> <span class=\"n\">comparer<\/span> <span class=\"n\">array1<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">index<\/span><span class=\"p\">]<\/span> <span class=\"n\">array2<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">index<\/span><span class=\"p\">]<\/span>\n            <span class=\"k\">if<\/span> <span class=\"n\">result<\/span> <span class=\"o\">&lt;&gt;<\/span> <span class=\"mi\">0<\/span> <span class=\"k\">then<\/span> <span class=\"n\">result<\/span> <span class=\"k\">else<\/span>\n            <span class=\"n\">loop<\/span> <span class=\"p\">(<\/span><span class=\"n\">index<\/span><span class=\"o\">+<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"n\">loop<\/span> <span class=\"mi\">0<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>It took some care to realize this performance improvement, early attempts were actually worse.  So keep in mind that testing and IL inspection will be necessary to know for sure if a recursive implementation is a problem. It often is not.<\/p>\n\n<h3 id=\"notes-on-benchmarking\">Notes on Benchmarking<\/h3>\n\n<p>Benchmarking managed code isn\u2019t easy.  As well as dealing with non deterministic hardware and operating systems just like you do with C\/C++, you also add the complication of the JIT, \nthe runtime, and garbage collection.  All of these things can cause code to run faster one moment, and slower the next.  Especially when looking for marginal\ngains you can easily fool yourself into thinking you have made progress when you have actually regressed, or vice versa.  Also you may have achieved a slight runtime\nimprovement for <em>your<\/em> function, but generated more garbage that has to be collected, leading to a net loss.  Or maybe you thrashed the L1 cache with your \nnew algorithm such that the next function goes slower, when run in the context of a full program.  These can be hard to identify in a benchmark. This is why\nI cringe a bit when I see people say \u201cyou can optimize it later when you identify that it is a bottleneck\u201d.  Identifying bottlenecks can be hard. If you \nsee easy ways to avoid pointer hopping or creating garbage, take them.<\/p>\n\n<p>I used the <a href=\"https:\/\/github.com\/PerfDotNet\/BenchmarkDotNet\">BenchmarkDotNet<\/a> library which helps solve some, but not all, of these challenges.  It will \nautomatically warm up the JIT for you, figure out how many trials need to run for each test to get good data, and report on memory usage and GC events\n(though this feature has some bugs, so be careful).  It also spits out nice reports on the results in HTML, CSV, and Markdown formats.  The Markdown\nformat is very handy as you can paste it into your Pull Requests. You can see a sample stub that I used <a href=\"\/src\/array-perf.fs\">here<\/a>.<\/p>\n\n<h3 id=\"you-can-do-this-too\">You can do this too<\/h3>\n\n<p>If you are interested in improving the quality or performance of software in the world, consider doing something about it.  You do not need to be \nhighly skilled or experienced. I am just an average web developer by day, not a language architect or assembler expert or anything.  You just need some \npatience.  Learning how a given project\u2019s repository and build process works is often the hardest part. Ask questions of the community, don\u2019t\nworry about seeming dumb. You will get less dumb every time you ask a dumb question.  Pick your favorite open source language or library, make it \nbetter.  Code bases are huge and even those written by grey beard wizards will have mistakes and bottlenecks that you can find and fix.  If the code\nbase is way above your head, start with improving documentation or error messages or other important but not so glamorous work.\nIt is always highly appreciated, and can be a way to familiarize yourself with the project and endear yourself to the other team members. Plus it also makes\nthe world a better place.<\/p>\n\n<h3 id=\"what-does-this-mean-for-fsharp\">What does this mean for FSharp<\/h3>\n\n<p>The net effect of all of this for F# programs out there will vary considerably. For the changes I\u2019ve been working on you need to be making use of arrays \n(you should! Learn about cache misses).  There are PRs from other people for performance improvements in other areas too, which is great to see. \nIf you are using arrays and using the core library Array module, things will just go faster. Whether it makes a substantive difference\njust depends on your use case.  For fun I put together a toy example that hits a lot of the key functions that have been sped up, and compared the current\n4.4.0 Core lib against what will hopefully all get merged into 4.4.1:<\/p>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">(* Init,create and map faster due to array bounds check elision *)<\/span>\n<span class=\"k\">let<\/span> <span class=\"n\">array1<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">init<\/span> <span class=\"nc\">TEN_MILLION<\/span> <span class=\"p\">(<\/span><span class=\"k\">fun<\/span> <span class=\"n\">i<\/span> <span class=\"o\">-&gt;<\/span>  <span class=\"n\">i<\/span><span class=\"p\">)<\/span>                                               \n<span class=\"k\">let<\/span> <span class=\"n\">array2<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">create<\/span> <span class=\"nc\">TEN_MILLION<\/span> <span class=\"mi\">5<\/span>                \n<span class=\"k\">let<\/span> <span class=\"n\">added<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">map2<\/span> <span class=\"p\">(<\/span><span class=\"k\">fun<\/span> <span class=\"n\">x<\/span> <span class=\"n\">y<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">x<\/span><span class=\"o\">+<\/span><span class=\"n\">y<\/span><span class=\"p\">)<\/span> <span class=\"n\">array1<\/span> <span class=\"n\">array2<\/span>\n\n<span class=\"c\">(* Rev faster due to array bounds elision and micro optimizations *)<\/span>\n<span class=\"k\">let<\/span> <span class=\"n\">backwards<\/span> <span class=\"o\">=<\/span> <span class=\"n\">added<\/span> <span class=\"o\">|&gt;<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">rev<\/span>        \n\n<span class=\"c\">(* AverageBy is much faster as it now no longer just calls into Seq.AverageBy *)<\/span>\n<span class=\"k\">let<\/span> <span class=\"n\">average<\/span> <span class=\"o\">=<\/span> <span class=\"n\">backwards<\/span> <span class=\"o\">|&gt;<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">averageBy<\/span> <span class=\"p\">(<\/span><span class=\"k\">fun<\/span> <span class=\"n\">x<\/span><span class=\"o\">-&gt;<\/span> <span class=\"p\">(<\/span><span class=\"kt\">float<\/span><span class=\"p\">)<\/span><span class=\"n\">x<\/span><span class=\"p\">)<\/span>        \n\n<span class=\"c\">(* Use aggregating Parallel.For loop *)<\/span>\n<span class=\"k\">let<\/span> <span class=\"n\">greaterThan400<\/span> <span class=\"o\">=<\/span> <span class=\"n\">backwards<\/span>\n                     <span class=\"o\">|&gt;<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"nn\">Parallel<\/span><span class=\"p\">.<\/span><span class=\"n\">choose<\/span> <span class=\"p\">(<\/span><span class=\"k\">fun<\/span> <span class=\"n\">x<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"k\">match<\/span> <span class=\"n\">x<\/span> <span class=\"k\">with<\/span> \n                                                        <span class=\"o\">|<\/span> <span class=\"n\">x<\/span> <span class=\"k\">when<\/span> <span class=\"n\">x<\/span> <span class=\"o\">&gt;<\/span> <span class=\"mi\">400<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nc\">Some<\/span> <span class=\"n\">x<\/span>\n                                                        <span class=\"o\">|<\/span> <span class=\"n\">_<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nc\">None<\/span> <span class=\"p\">)<\/span>\n                                            \n<span class=\"c\">(* Partition faster and uses less memory due to new algorithm *)<\/span>\n<span class=\"k\">let<\/span> <span class=\"p\">(<\/span><span class=\"n\">even<\/span><span class=\"o\">,<\/span><span class=\"n\">odd<\/span><span class=\"p\">)<\/span> <span class=\"o\">=<\/span> <span class=\"n\">greaterThan400<\/span> <span class=\"o\">|&gt;<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">partition<\/span> <span class=\"p\">(<\/span><span class=\"k\">fun<\/span> <span class=\"n\">x<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">x<\/span> <span class=\"o\">%<\/span> <span class=\"mi\">2<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span>        \n\n<span class=\"c\">(* Filter faster due to using preallocated array instead of List&lt;T&gt; *)<\/span>\n<span class=\"k\">let<\/span> <span class=\"n\">filtered<\/span> <span class=\"o\">=<\/span> <span class=\"n\">even<\/span> <span class=\"o\">|&gt;<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">filter<\/span><span class=\"p\">(<\/span><span class=\"k\">fun<\/span> <span class=\"n\">x<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">x<\/span> <span class=\"o\">%<\/span> <span class=\"mi\">4<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span>\n\n<\/code><\/pre><\/div><\/div>\n\n<h3 id=\"results\">Results<\/h3>\n\n<div class=\"language-ini highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>\n<span class=\"err\">Host<\/span> <span class=\"err\">Process<\/span> <span class=\"err\">Environment<\/span> <span class=\"err\">Information:<\/span>\n<span class=\"py\">BenchmarkDotNet<\/span><span class=\"p\">=<\/span><span class=\"s\">v0.9.8.0<\/span>\n<span class=\"py\">OS<\/span><span class=\"p\">=<\/span><span class=\"s\">Microsoft Windows NT 6.2.9200.0<\/span>\n<span class=\"py\">Processor<\/span><span class=\"p\">=<\/span><span class=\"s\">Intel(R) Core(TM) i7-4712HQ CPU 2.30GHz, ProcessorCount=8<\/span>\n<span class=\"py\">Frequency<\/span><span class=\"p\">=<\/span><span class=\"s\">2240908 ticks, Resolution=446.2477 ns, Timer=TSC<\/span>\n<span class=\"py\">CLR<\/span><span class=\"p\">=<\/span><span class=\"s\">MS.NET 4.0.30319.42000, Arch=64-bit RELEASE [RyuJIT]<\/span>\n<span class=\"py\">GC<\/span><span class=\"p\">=<\/span><span class=\"s\">Concurrent Workstation<\/span>\n<span class=\"py\">JitModules<\/span><span class=\"p\">=<\/span><span class=\"s\">clrjit-v4.6.1590.0<\/span>\n\n<span class=\"py\">Type<\/span><span class=\"p\">=<\/span><span class=\"s\">SIMDBenchmark  Mode=Throughput  Platform=X64  <\/span>\n<span class=\"py\">Jit<\/span><span class=\"p\">=<\/span><span class=\"s\">RyuJit  GarbageCollection=Concurrent Workstation  <\/span>\n\n<\/code><\/pre><\/div><\/div>\n\n<table>\n  <thead>\n    <tr>\n      <th>Method<\/th>\n      <th>Length<\/th>\n      <th>Median<\/th>\n      <th>StdDev<\/th>\n      <th>Gen 0<\/th>\n      <th>Gen 1<\/th>\n      <th>Gen 2<\/th>\n      <th>Bytes Allocated\/Op<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>Old<\/td>\n      <td>10<\/td>\n      <td>3.4036 us<\/td>\n      <td>0.0806 us<\/td>\n      <td>0.07<\/td>\n      <td>0.00<\/td>\n      <td>-<\/td>\n      <td>852.03<\/td>\n    <\/tr>\n    <tr>\n      <td>New<\/td>\n      <td>10<\/td>\n      <td>3.4044 us<\/td>\n      <td>0.3243 us<\/td>\n      <td>0.08<\/td>\n      <td>0.00<\/td>\n      <td>-<\/td>\n      <td>1,118.24<\/td>\n    <\/tr>\n    <tr>\n      <td>Old<\/td>\n      <td>1000<\/td>\n      <td>52.2478 us<\/td>\n      <td>4.7930 us<\/td>\n      <td>2.15<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>31,762.76<\/td>\n    <\/tr>\n    <tr>\n      <td>New<\/td>\n      <td>1000<\/td>\n      <td>41.3602 us<\/td>\n      <td>2.7741 us<\/td>\n      <td>1.37<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>22,699.78<\/td>\n    <\/tr>\n    <tr>\n      <td>Old<\/td>\n      <td>100000<\/td>\n      <td>6,001.7350 us<\/td>\n      <td>286.9376 us<\/td>\n      <td>58.77<\/td>\n      <td>2.10<\/td>\n      <td>74.12<\/td>\n      <td>3,114,798.18<\/td>\n    <\/tr>\n    <tr>\n      <td>New<\/td>\n      <td>100000<\/td>\n      <td>3,296.3410 us<\/td>\n      <td>89.5167 us<\/td>\n      <td>-<\/td>\n      <td>-<\/td>\n      <td>78.91<\/td>\n      <td>3,254,820.11<\/td>\n    <\/tr>\n    <tr>\n      <td>Old<\/td>\n      <td>1000000<\/td>\n      <td>40,985.6462 us<\/td>\n      <td>830.1541 us<\/td>\n      <td>556.34<\/td>\n      <td>-<\/td>\n      <td>211.89<\/td>\n      <td>30,759,505.83<\/td>\n    <\/tr>\n    <tr>\n      <td>New<\/td>\n      <td>1000000<\/td>\n      <td>33,555.2876 us<\/td>\n      <td>3,514.3688 us<\/td>\n      <td>519.70<\/td>\n      <td>-<\/td>\n      <td>229.11<\/td>\n      <td>29,579,065.56<\/td>\n    <\/tr>\n    <tr>\n      <td>Old<\/td>\n      <td>10000000<\/td>\n      <td>405,780.3801 us<\/td>\n      <td>8,032.9328 us<\/td>\n      <td>5,660.00<\/td>\n      <td>-<\/td>\n      <td>227.00<\/td>\n      <td>333,268,994.49<\/td>\n    <\/tr>\n    <tr>\n      <td>New<\/td>\n      <td>10000000<\/td>\n      <td>286,415.5958 us<\/td>\n      <td>7,394.8703 us<\/td>\n      <td>5,049.00<\/td>\n      <td>-<\/td>\n      <td>183.00<\/td>\n      <td>287,616,350.72<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n","pubDate":"Sat, 13 Aug 2016 19:17:27 +0000","link":"https:\/\/jackmott.github.io\/\/programming\/2016\/08\/13\/adventures-in-fsharp.html","guid":"https:\/\/jackmott.github.io\/\/programming\/2016\/08\/13\/adventures-in-fsharp.html","category":"programming"},{"title":"Making the obvious code fast","description":"<p><a href=\"http:\/\/number-none.com\/blow\/\">Jonathan Blow<\/a> of \u201cThe Witness\u201d fame likes to talk about just typing the obvious code first.  Usually it will turn\nout to be fast enough.  If it doesn\u2019t, you can go back and optimize it later.  His thoughts come in the context of working on games in C\/C++. \nI think these languages, with modern incarnations of their compilers, are compatible with this philosophy. Not only are the compilers very \nmature but they are low level enough that you are forced to do things by hand, and think about what the machine is doing most of the time, especially if\nyou stick to C or a \u2018mostly C\u2019 subset of C++. However in most higher level languages, there tend to be performance traps where the obvious, or idiomatic solution is \nparticularly bad.<\/p>\n\n<p>What counts as obvious or idiomatic, is of course often a matter of opinion.  The language itself may encourage certain choices\nby making them easier to type, or highlighting them in documentation and teaching materials.  The community that grows up around a language\nmay just come to prefer certain constructs and encourage others to use them. It is very common to see programmers encouraged to use\nhigh level constructs over lower level ones, in the interest of readability and simplicity.  This is a worthy ideal, but often people\naren\u2019t aware of what the cost really is.  Some of these constructs have a much higher cost than people realize.<\/p>\n\n<p>In this article I will explore a number of languages, with a toy map and reduce example. Within each language, I will explore \na number of approaches, ranging from high level to hand coded imperative loops and SIMD operations.  Some of the performance pitfalls I will show may be specific\nto this toy example. With a different toy example, the languages that excel and those that do poorly could be totally different.  This is meant\nmerely to explore, and get people thinking about the performance cost of abstractions. For each case I will show code examples so you\ncan consider the differences in complexity.<\/p>\n\n<h2 id=\"the-task\">The Task<\/h2>\n\n<p>We wish to take an array of 32 million 64bit floating point values, and compute the sum of their squares. This will let us explore some\nfundamental abilities of various languages. Their ability to iterate over arrays efficiently, whether they can vectorize basic loops, and \nwhether higher order functions like map and reduce compile to efficient code. When applicable, I will show runtimes of both map and reduce, \nso we get insight into whether the language can stream higher order functions together, and also the runtime with a single\nreduce or fold operation.<\/p>\n\n<h2 id=\"the-results\">The Results<\/h2>\n\n<ul>\n  <li><a href=\"#benchmark\">Benchmark Details<\/a><\/li>\n<\/ul>\n\n<h3 id=\"c---17-milliseconds\">C - 17 milliseconds<\/h3>\n\n<div class=\"language-c highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"kt\">double<\/span> <span class=\"n\">sum<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">.<\/span><span class=\"mi\">0<\/span><span class=\"p\">;<\/span>    \n    <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">COUNT<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span><span class=\"o\">++<\/span><span class=\"p\">)<\/span> \n    <span class=\"p\">{<\/span>\n        <span class=\"kt\">double<\/span> <span class=\"n\">v<\/span> <span class=\"o\">=<\/span> <span class=\"n\">values<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span> <span class=\"o\">*<\/span> <span class=\"n\">values<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">];<\/span> \n        <span class=\"n\">sum<\/span> <span class=\"o\">+=<\/span> <span class=\"n\">v<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>ANSI C is a bare bones language, no higher order functions or loop abstractions exist to even think about, so this imperative loop is what most\nprogrammers wil turn to to complete this task. If I thought that this would be a performance critical piece of code, I might use SIMD intrinsics, \nwhich requires this nasty mess:<\/p>\n\n<h3 id=\"c---simd-explicit---17-milliseconds\">C - SIMD Explicit - 17 milliseconds<\/h3>\n\n<div class=\"language-c highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"n\">__m256d<\/span> <span class=\"n\">vsum<\/span> <span class=\"o\">=<\/span> <span class=\"n\">_mm256_setzero_pd<\/span><span class=\"p\">();<\/span>\n    <span class=\"k\">for<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">COUNT<\/span><span class=\"o\">\/<\/span><span class=\"mi\">4<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span><span class=\"o\">=<\/span><span class=\"n\">i<\/span><span class=\"o\">+<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"n\">__m256d<\/span> <span class=\"n\">v<\/span> <span class=\"o\">=<\/span> <span class=\"n\">values<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">];<\/span>\n        <span class=\"n\">vsum<\/span> <span class=\"o\">=<\/span> <span class=\"n\">_mm256_add_pd<\/span><span class=\"p\">(<\/span><span class=\"n\">vsum<\/span><span class=\"p\">,<\/span><span class=\"n\">_mm256_mul_pd<\/span><span class=\"p\">(<\/span><span class=\"n\">v<\/span><span class=\"p\">,<\/span><span class=\"n\">v<\/span><span class=\"p\">));<\/span>\n    <span class=\"p\">}<\/span>\n    <span class=\"kt\">double<\/span> <span class=\"o\">*<\/span><span class=\"n\">tsum<\/span> <span class=\"o\">=<\/span> <span class=\"o\">&amp;<\/span><span class=\"n\">vsum<\/span><span class=\"p\">;<\/span>\n    <span class=\"kt\">double<\/span> <span class=\"n\">sum<\/span> <span class=\"o\">=<\/span> <span class=\"n\">tsum<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span><span class=\"o\">+<\/span><span class=\"n\">tsum<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span><span class=\"o\">+<\/span><span class=\"n\">tsum<\/span><span class=\"p\">[<\/span><span class=\"mi\">2<\/span><span class=\"p\">]<\/span><span class=\"o\">+<\/span><span class=\"n\">tsum<\/span><span class=\"p\">[<\/span><span class=\"mi\">3<\/span><span class=\"p\">];<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>However, notice that the runtime is the same for the obvious and SIMD versions!  It turns out that the obvious code was automatically turned into SIMD\nenhanced machine instructions. A process called \u201cAuto vectorization\u201d.  Visual C++ is not known for being the most clever of C++ compilers but it still \ngets this right:<\/p>\n\n<pre><code class=\"language-asm\">double sum = 0.0;    \n\tfor (int i = 0; i &lt; COUNT; i++) {\n00007FF7085C1120  vmovupd     ymm0,ymmword ptr [rcx]  \n00007FF7085C1124  lea         rcx,[rcx+40h]  \n\t\tdouble v = values[i] * values[i];  \/\/square em\n00007FF7085C1128  vmulpd      ymm2,ymm0,ymm0  \n00007FF7085C112C  vmovupd     ymm0,ymmword ptr [rcx-20h]  \n00007FF7085C1131  vaddpd      ymm4,ymm2,ymm4  \n00007FF7085C1135  vmulpd      ymm2,ymm0,ymm0  \n00007FF7085C1139  vaddpd      ymm3,ymm2,ymm5  \n00007FF7085C113D  vmovupd     ymm5,ymm3  \n00007FF7085C1141  sub         rdx,1  \n00007FF7085C1145  jne         imperative+80h (07FF7085C1120h)  \n\t\tsum += v;\n\t}\n\n<\/code><\/pre>\n\n<p>To get the SIMD instructions used here, which can operate on 4 doubles at a time, you have to specify to the compiler that you want \u2018fast floating point\u2019\nand specify that you want to target AVX2 instructions as well. Results will be different when vectorized, though they will actually be more \naccurate, not less. (in this case, maybe all?)<\/p>\n\n<h3 id=\"c-linq-select-sum---260-milliseconds\">C# Linq Select Sum - 260 milliseconds<\/h3>\n\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"kt\">var<\/span> <span class=\"n\">sum<\/span> <span class=\"p\">=<\/span> <span class=\"n\">values<\/span><span class=\"p\">.<\/span><span class=\"nf\">Sum<\/span><span class=\"p\">(<\/span><span class=\"n\">x<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"n\">x<\/span> <span class=\"p\">*<\/span> <span class=\"n\">x<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h3 id=\"c-linq-aggregate---280-milliseconds\">C# Linq Aggregate - 280 milliseconds<\/h3>\n\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"kt\">var<\/span> <span class=\"n\">sum<\/span> <span class=\"p\">=<\/span> <span class=\"n\">values<\/span><span class=\"p\">.<\/span><span class=\"nf\">Aggregate<\/span><span class=\"p\">(<\/span><span class=\"m\">0.0<\/span><span class=\"p\">,(<\/span><span class=\"n\">acc<\/span><span class=\"p\">,<\/span> <span class=\"n\">x<\/span><span class=\"p\">)<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"n\">acc<\/span> <span class=\"p\">+<\/span> <span class=\"n\">x<\/span> <span class=\"p\">*<\/span> <span class=\"n\">x<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h3 id=\"c-for-loop---34-milliseconds\">C# for loop - 34 milliseconds<\/h3>\n\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"kt\">double<\/span> <span class=\"n\">sum<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0.0<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">foreach<\/span> <span class=\"p\">(<\/span><span class=\"kt\">var<\/span> <span class=\"n\">v<\/span> <span class=\"k\">in<\/span> <span class=\"n\">values<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>       \n        <span class=\"kt\">double<\/span> <span class=\"n\">square<\/span> <span class=\"p\">=<\/span> <span class=\"n\">v<\/span> <span class=\"p\">*<\/span> <span class=\"n\">v<\/span><span class=\"p\">;<\/span>\n        <span class=\"n\">sum<\/span> <span class=\"p\">+=<\/span> <span class=\"n\">square<\/span><span class=\"p\">;<\/span>       \n    <span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Stepping up a level to C#, we have a couple of idiomatic solutions.  Many C# programmers today might use Linq which as you can see is much slower. It also creates a \nlot of garbage, putting more pressure on the garbage collector. Oddly, the Aggregate function, which is equivalent to fold or reduce in most other languages, is slower\ndespite being a single step instead of two.  The foreach loop in the second example is also commonly used.  While this pattern has big \nperformance pitfalls when used on collections like List&lt;T&gt;, with arrays it compiles to efficient code. This is nice as it saves you some typing without \nruntime penalty. The  runtime here is still twice as slow as the C code, but that is entirely due to not being automatically vectorized.<br \/>\nWith the .NET JIT, it is not considered a worthwhile tradeoff to do this particular optimization.<\/p>\n\n<p>With C# you also have to take some care with array access in loops, \nor <a href=\"http:\/\/www.codeproject.com\/Articles\/844781\/Digging-Into-NET-Loop-Performance-Bounds-checking\">bounds checking overhead can be introduced<\/a>. In this case the \nJIT gets it right, and there is no bounds checking overhead.<\/p>\n\n<h3 id=\"c-simd-explicit---17-milliseconds\">C# SIMD Explicit - 17 milliseconds<\/h3>\n<div class=\"language-c# highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"n\">Vector<\/span><span class=\"p\">&lt;<\/span><span class=\"kt\">double<\/span><span class=\"p\">&gt;<\/span> <span class=\"n\">vsum<\/span> <span class=\"p\">=<\/span> <span class=\"k\">new<\/span> <span class=\"n\">Vector<\/span><span class=\"p\">&lt;<\/span><span class=\"kt\">double<\/span><span class=\"p\">&gt;(<\/span><span class=\"m\">0.0<\/span><span class=\"p\">);<\/span>\n    <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"p\">&lt;<\/span> <span class=\"n\">COUNT<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"p\">+=<\/span> <span class=\"n\">Vector<\/span><span class=\"p\">&lt;<\/span><span class=\"kt\">double<\/span><span class=\"p\">&gt;.<\/span><span class=\"n\">Count<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"kt\">var<\/span> <span class=\"k\">value<\/span> <span class=\"p\">=<\/span> <span class=\"k\">new<\/span> <span class=\"n\">Vector<\/span><span class=\"p\">&lt;<\/span><span class=\"kt\">double<\/span><span class=\"p\">&gt;(<\/span><span class=\"n\">values<\/span><span class=\"p\">,<\/span> <span class=\"n\">i<\/span><span class=\"p\">);<\/span>\n        <span class=\"n\">vsum<\/span> <span class=\"p\">=<\/span> <span class=\"n\">vsum<\/span> <span class=\"p\">+<\/span> <span class=\"p\">(<\/span><span class=\"k\">value<\/span> <span class=\"p\">*<\/span> <span class=\"k\">value<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n    <span class=\"kt\">double<\/span> <span class=\"n\">sum<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">for<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"p\">=<\/span> <span class=\"m\">0<\/span><span class=\"p\">;<\/span> <span class=\"n\">i<\/span> <span class=\"p\">&lt;<\/span> <span class=\"n\">Vector<\/span><span class=\"p\">&lt;<\/span><span class=\"kt\">double<\/span><span class=\"p\">&gt;.<\/span><span class=\"n\">Count<\/span><span class=\"p\">;<\/span><span class=\"n\">i<\/span><span class=\"p\">++)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"n\">sum<\/span> <span class=\"p\">+=<\/span> <span class=\"n\">vsum<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">];<\/span>\n    <span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>While the .NET JIT won\u2019t do SIMD automatically, we can explicitly use some SIMD instructions, and achieve performance nearly identical to C.  An advantage here for C# is that the SIMD code is a\nbit less nasty than using intrinsics, and that particular instructions whether they be AVX2, SSE2, NEON, or whatever the hardware supports, can be decided\nupon at runtime.  Whereas the C code above would require separate compilation for each architecture. A disadvantage for C# is that not all SIMD instructions\nare exposed by the Vector library, so something like <a href=\"https:\/\/github.com\/Auburns\/FastNoiseSIMD\">SIMD enhanced noise functions<\/a> can\u2019t be done with nearly the\nsame performance. As well, the machine code produced by the Vector library is not always as efficient when you step out of toy examples.<\/p>\n\n<h3 id=\"f---127-milliseconds\">F# - 127 milliseconds<\/h3>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"k\">let<\/span> <span class=\"n\">sum<\/span> <span class=\"o\">=<\/span>\n        <span class=\"n\">values<\/span>\n        <span class=\"o\">|&gt;<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">map<\/span> <span class=\"n\">squares<\/span>\n        <span class=\"o\">|&gt;<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">sum<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>The obvious F# code is beautiful, I like typing this, and I like working with it.  But performance is terrible. Just as with C# you get no auto vectorization,\nas they use the same JIT.  Additionally the array is iterated over twice, once to map them to squares, and once to sum them. Finally, since \nimmutability is the default, each operation returns a new array, incurring allocation costs and GC pressure. So the total performance impact\non an application is likely to be worse than this micro benchmark would suggest.<\/p>\n\n<h3 id=\"f-streams---98-milliseconds\">F# Streams - 98 milliseconds<\/h3>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"k\">let<\/span> <span class=\"n\">sum<\/span> <span class=\"o\">=<\/span> \n        <span class=\"n\">values<\/span>\n        <span class=\"o\">|&gt;<\/span> <span class=\"nn\">Stream<\/span><span class=\"p\">.<\/span><span class=\"n\">map<\/span> <span class=\"n\">square<\/span>\n        <span class=\"o\">|&gt;<\/span> <span class=\"nn\">Stream<\/span><span class=\"p\">.<\/span><span class=\"n\">sum<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>F# is a functional first language, rather than a pure functional language like Haskell. If you do happen to use pure functions, you can stream your\nmap and sum operations together, and avoid iterating over the array twice.  The <a href=\"https:\/\/github.com\/nessos\/Streams\">Nessos Streams<\/a> library provides this, \nwith a nice performance improvement as a result.<\/p>\n\n<h3 id=\"f-fold---75-milliseconds\">F# Fold - 75 milliseconds<\/h3>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"k\">let<\/span> <span class=\"n\">sum<\/span> <span class=\"o\">=<\/span> \n        <span class=\"n\">values<\/span>\n        <span class=\"o\">|&gt;<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">fold<\/span> <span class=\"p\">(<\/span><span class=\"k\">fun<\/span> <span class=\"n\">acc<\/span> <span class=\"n\">x<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">acc<\/span> <span class=\"o\">+<\/span> <span class=\"n\">x<\/span><span class=\"o\">*<\/span><span class=\"n\">x<\/span><span class=\"p\">)<\/span> <span class=\"mi\">0<\/span><span class=\"o\">.<\/span><span class=\"mi\">0<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>When we use a single fold operation, we no longer iterate over the collection twice and allocate extra memory, and runtime improves even more.  Since\nthere is no overhead for streaming together multiple higher order functions as there is in the Streams library, it does slightly better.<\/p>\n\n<h3 id=\"f-imperative---38-milliseconds\">F# Imperative - 38 milliseconds<\/h3>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"k\">let<\/span> <span class=\"k\">mutable<\/span> <span class=\"n\">sum<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"o\">.<\/span><span class=\"mi\">0<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span> <span class=\"k\">to<\/span> <span class=\"n\">values<\/span><span class=\"o\">.<\/span><span class=\"nc\">Length<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span> <span class=\"k\">do<\/span>\n            <span class=\"k\">let<\/span> <span class=\"n\">x<\/span> <span class=\"o\">=<\/span> <span class=\"n\">values<\/span><span class=\"o\">.<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span>\n            <span class=\"n\">sum<\/span> <span class=\"o\">&lt;-<\/span> <span class=\"n\">sum<\/span> <span class=\"o\">+<\/span> <span class=\"n\">x<\/span><span class=\"o\">*<\/span><span class=\"n\">x<\/span>            \n<\/code><\/pre><\/div><\/div>\n\n<p>One of the nice things about F#, is that while it is a functional leaning language, very few barriers are put in your way if you want\nto go imperative for the sake of speed.  Write a normal for loop, and you get the same performance as SSE vectorized C.<\/p>\n\n<h3 id=\"f-simd---18ms\">F# SIMD - 18ms<\/h3>\n\n<div class=\"language-ocaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"k\">let<\/span> <span class=\"n\">sum<\/span> <span class=\"o\">=<\/span>\n        <span class=\"n\">values<\/span>\n        <span class=\"o\">|&gt;<\/span> <span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"nn\">SIMD<\/span><span class=\"p\">.<\/span><span class=\"n\">fold<\/span> <span class=\"p\">(<\/span><span class=\"k\">fun<\/span> <span class=\"n\">acc<\/span> <span class=\"n\">v<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">acc<\/span> <span class=\"o\">+<\/span><span class=\"n\">v<\/span><span class=\"o\">*<\/span><span class=\"n\">v<\/span><span class=\"p\">)<\/span> <span class=\"p\">(<\/span><span class=\"o\">+<\/span><span class=\"p\">)<\/span> <span class=\"mi\">0<\/span><span class=\"o\">.<\/span><span class=\"mi\">0<\/span>    \n<\/code><\/pre><\/div><\/div>\n\n<p>Now to get serious. First we use fold, so that we can combine the summing and squaring into a single pass. Then we use the\n<a href=\"https:\/\/github.com\/jackmott\/SIMDArray\">SIMDArray extensions<\/a> that I have been working on which let you take full advantage\nof SIMD with more idiomatic F#.  Performance here is great, nearly as fast as C, but it took a lot of work to get here.\nAt the moment there is no way to combine the lazy stream optimization with the SIMD ones. If you want to filter-&gt;map-&gt;reduce you will\nstill be doing a lot of extra work.  This should be possible in principle though. Please submit a PR!<\/p>\n\n<h3 id=\"rust---34ms\">Rust - 34ms<\/h3>\n\n<div class=\"language-rust highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"k\">let<\/span> <span class=\"n\">sum<\/span> <span class=\"o\">=<\/span> <span class=\"n\">values<\/span><span class=\"nf\">.iter<\/span><span class=\"p\">()<\/span><span class=\"nf\">.\n                map<\/span><span class=\"p\">(|<\/span><span class=\"n\">x<\/span><span class=\"p\">|<\/span> <span class=\"n\">x<\/span><span class=\"o\">*<\/span><span class=\"n\">x<\/span><span class=\"p\">)<\/span><span class=\"nf\">.        \n                sum<\/span><span class=\"p\">()<\/span>  \n<\/code><\/pre><\/div><\/div>\n\n<p>Rust achieves impressive numbers with the most obvious approach. This is super cool. I feel that this behavior should be the goal for any language \noffering these kinds of higher order functions as part of the language or core library. Using a traditional for loop or a \u2018for x in y\u2019 style loop\nis also just as fast. It is also possible to use rust intrinsics to get the same speed as the AVX2 vectorized C code here, but to use those you have to \nwrite out the loop explicitly:<\/p>\n\n<h3 id=\"rust-simd---17ms\">Rust SIMD - 17ms<\/h3>\n\n<div class=\"language-rust highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"k\">let<\/span> <span class=\"k\">mut<\/span> <span class=\"n\">sum<\/span> <span class=\"o\">=<\/span> <span class=\"mf\">0.0<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">unsafe<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">for<\/span> <span class=\"n\">v<\/span> <span class=\"n\">in<\/span> <span class=\"n\">values<\/span> <span class=\"p\">{<\/span>\n            <span class=\"k\">let<\/span> <span class=\"n\">x<\/span> <span class=\"p\">:<\/span> <span class=\"nb\">f64<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">std<\/span><span class=\"p\">::<\/span><span class=\"nn\">intrinsics<\/span><span class=\"p\">::<\/span><span class=\"nf\">fmul_fast<\/span><span class=\"p\">(<\/span><span class=\"o\">*<\/span><span class=\"n\">v<\/span><span class=\"p\">,<\/span><span class=\"o\">*<\/span><span class=\"n\">v<\/span><span class=\"p\">);<\/span>\n            <span class=\"n\">sum<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">std<\/span><span class=\"p\">::<\/span><span class=\"nn\">intrinsics<\/span><span class=\"p\">::<\/span><span class=\"nf\">fadd_fast<\/span><span class=\"p\">(<\/span><span class=\"n\">sum<\/span><span class=\"p\">,<\/span><span class=\"n\">x<\/span><span class=\"p\">);<\/span> \n        <span class=\"p\">}<\/span>\n    <span class=\"p\">}<\/span>\n    <span class=\"n\">sum<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>It would be nice if the rustc compiler had an option to just apply this globally, so you could use the higher order functions. Also,\nthese features are marked as unstable, and likely to remain unstable forever.  This might make it problematic to use this feature for\nany important production project.  It would also be nice if the unsafe block was not required. \nHopefully the Rust maintainers have a plan to make this better.<\/p>\n\n<h3 id=\"javascript-map-reduce-nodejs-10000ms\">Javascript map reduce (node.js) 10,000ms<\/h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">var<\/span> <span class=\"nx\">sum<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">values<\/span><span class=\"p\">.<\/span><span class=\"nx\">map<\/span><span class=\"p\">(<\/span><span class=\"nx\">x<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nx\">x<\/span><span class=\"o\">*<\/span><span class=\"nx\">x<\/span><span class=\"p\">).<\/span>\n                 <span class=\"nx\">reduce<\/span><span class=\"p\">(<\/span> <span class=\"p\">(<\/span><span class=\"nx\">total<\/span><span class=\"p\">,<\/span><span class=\"nx\">num<\/span><span class=\"p\">,<\/span><span class=\"nx\">index<\/span><span class=\"p\">,<\/span><span class=\"nx\">array<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nx\">total<\/span><span class=\"o\">+<\/span><span class=\"nx\">num<\/span><span class=\"p\">,<\/span><span class=\"mf\">0.0<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h3 id=\"javascript-reduce-nodejs-800-and-then-300-milliseconds\">Javascript reduce (node.js) 800 and then 300 milliseconds<\/h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">var<\/span> <span class=\"nx\">sum<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">values<\/span><span class=\"p\">.<\/span><span class=\"nx\">reduce<\/span><span class=\"p\">(<\/span> <span class=\"p\">(<\/span><span class=\"nx\">total<\/span><span class=\"p\">,<\/span><span class=\"nx\">num<\/span><span class=\"p\">,<\/span><span class=\"nx\">index<\/span><span class=\"p\">,<\/span><span class=\"nx\">array<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nx\">total<\/span><span class=\"o\">+<\/span><span class=\"nx\">num<\/span><span class=\"o\">*<\/span><span class=\"nx\">num<\/span><span class=\"p\">,<\/span><span class=\"mf\">0.0<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>It is common to see these higher order javascript functions suggested as the most elegant way to do this, but it is incredibly slow. Simplifying the \ncombined map and reduce improves runtime by an order of magnitude to 800ms, though after 3 or 4 iterations the JIT does some magic and runtime\ndrops to 300ms thereafter.  This represents the first time I have seen any substantive JIT optimization happen during runtime in the wild!<\/p>\n\n<h3 id=\"javascript-foreach-nodejs-800-and-then-300-milliseconds\">Javascript foreach (node.js) 800 and then 300 milliseconds<\/h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"kd\">var<\/span> <span class=\"nx\">sum<\/span> <span class=\"o\">=<\/span> <span class=\"mf\">0.0<\/span><span class=\"p\">;<\/span>\n    <span class=\"nx\">array<\/span><span class=\"p\">.<\/span><span class=\"nx\">forEach<\/span><span class=\"p\">(<\/span> <span class=\"p\">(<\/span><span class=\"nx\">element<\/span><span class=\"p\">,<\/span><span class=\"nx\">index<\/span><span class=\"p\">,<\/span><span class=\"nx\">array<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nx\">sum<\/span> <span class=\"o\">+=<\/span> <span class=\"nx\">element<\/span><span class=\"o\">*<\/span><span class=\"nx\">element<\/span>  <span class=\"p\">)<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>Slightly less elegant but also a popular idiom in javascript, this is faster than map and reduce, but is still amazingly slow. Again, after\n3 or 4 iterations the JIT does some magic and it speeds up from around 800 to 300 milliseconds.<\/p>\n\n<h3 id=\"javascript-imperative-nodejs-37-milliseconds\">Javascript imperative (node.js) 37 milliseconds<\/h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>\n    <span class=\"kd\">var<\/span> <span class=\"nx\">sum<\/span> <span class=\"o\">=<\/span> <span class=\"mf\">0.0<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kd\">var<\/span> <span class=\"nx\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">;<\/span> <span class=\"nx\">i<\/span> <span class=\"o\">&lt;<\/span> <span class=\"nx\">values<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span><span class=\"p\">;<\/span><span class=\"nx\">i<\/span><span class=\"o\">++<\/span><span class=\"p\">){<\/span>\n        <span class=\"kd\">var<\/span> <span class=\"nx\">x<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">values<\/span><span class=\"p\">[<\/span><span class=\"nx\">i<\/span><span class=\"p\">];<\/span>\n        <span class=\"nx\">sum<\/span> <span class=\"o\">+=<\/span> <span class=\"nx\">x<\/span><span class=\"o\">*<\/span><span class=\"nx\">x<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n<\/code><\/pre><\/div><\/div>\n\n<p>Finally, when we get down to a basic imperative for loop, javascript performs comparably to SEE vectorized C.<\/p>\n\n<h3 id=\"java-streams-map-sum-138-milliseconds\">Java Streams Map Sum 138 milliseconds<\/h3>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"kt\">double<\/span> <span class=\"n\">sum<\/span> <span class=\"o\">=<\/span> <span class=\"n\">Arrays<\/span><span class=\"o\">.<\/span><span class=\"na\">stream<\/span><span class=\"o\">(<\/span><span class=\"n\">values<\/span><span class=\"o\">).<\/span>\n                        <span class=\"n\">map<\/span><span class=\"o\">(<\/span><span class=\"n\">x<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">x<\/span><span class=\"o\">*<\/span><span class=\"n\">x<\/span><span class=\"o\">).<\/span>\n                        <span class=\"n\">sum<\/span><span class=\"o\">();<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h3 id=\"java-streams-reduce-34-milliseconds\">Java Streams Reduce 34 milliseconds<\/h3>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"kt\">double<\/span> <span class=\"n\">sum<\/span> <span class=\"o\">=<\/span> <span class=\"n\">Arrays<\/span><span class=\"o\">.<\/span><span class=\"na\">stream<\/span><span class=\"o\">(<\/span><span class=\"n\">values<\/span><span class=\"o\">).<\/span>\n                        <span class=\"n\">reduce<\/span><span class=\"o\">(<\/span><span class=\"mi\">0<\/span><span class=\"o\">,(<\/span><span class=\"n\">acc<\/span><span class=\"o\">,<\/span><span class=\"n\">x<\/span><span class=\"o\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">acc<\/span><span class=\"o\">+<\/span><span class=\"n\">x<\/span><span class=\"o\">*<\/span><span class=\"n\">x<\/span><span class=\"o\">);<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Java 8 includes a very nice library called <a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/util\/stream\/package-summary.html\">stream<\/a> which provides higher\norder functions over collections in a lazy evaluated manner, similar to the F# Nessos streams library and Rust. Given that this is a lazy evaluated system, it is\nodd that there is such a performance difference between map then sum and a single reduction.  The reduce function is compiling down to the equivalent of SSE vectorized C,\nbut the map then sum is not even close. It turns out that the <code class=\"highlighter-rouge\">sum()<\/code> method on <code class=\"highlighter-rouge\">DoubleStream<\/code>:<\/p>\n\n<blockquote>\n  <p>may be implemented using compensated summation or other technique to reduce the error bound in the numerical sum compared to a simple summation of double values.<\/p>\n<\/blockquote>\n\n<p>A nice feature, but not clearly communicated by the method name!  If we tweak the java code to do normal summation the runtime remains as fast as SSE vectorized C, a nice \naccomplishment:<\/p>\n\n<h3 id=\"java-streams-map-reduce-34-milliseconds\">Java Streams Map Reduce 34 milliseconds<\/h3>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>    <span class=\"kt\">double<\/span> <span class=\"n\">sum<\/span> <span class=\"o\">=<\/span> <span class=\"n\">Arrays<\/span><span class=\"o\">.<\/span><span class=\"na\">stream<\/span><span class=\"o\">(<\/span><span class=\"n\">values<\/span><span class=\"o\">).<\/span>\n                        <span class=\"n\">map<\/span><span class=\"o\">(<\/span><span class=\"n\">x<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">x<\/span><span class=\"o\">*<\/span><span class=\"n\">x<\/span><span class=\"o\">).<\/span>\n                        <span class=\"n\">reduce<\/span><span class=\"o\">(<\/span><span class=\"mi\">0<\/span><span class=\"o\">,(<\/span><span class=\"n\">acc<\/span><span class=\"o\">,<\/span><span class=\"n\">x<\/span><span class=\"o\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">acc<\/span><span class=\"o\">+<\/span><span class=\"n\">x<\/span><span class=\"o\">);<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>There does not appear to be a way to get SIMD out of Java, either explicitly or via automatic vectorization by the Hotspot JVM. There are 3rd\nparty libraries available that do it by calling C++ code. I do see some literature stating that the JVM can and does auto-vectorize, but\nI\u2019m not seeing evidence of that in this case, or when I use a for loop, either.<\/p>\n\n<h3 id=\"go-for-range-37-milliseconds\">Go for Range 37 milliseconds<\/h3>\n\n<div class=\"language-go highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"x\">    <\/span><span class=\"n\">sum<\/span><span class=\"x\"> <\/span><span class=\"o\">:=<\/span><span class=\"x\"> <\/span><span class=\"m\">0.0<\/span><span class=\"x\">\n    <\/span><span class=\"k\">for<\/span><span class=\"x\"> <\/span><span class=\"n\">_<\/span><span class=\"p\">,<\/span><span class=\"n\">v<\/span><span class=\"x\"> <\/span><span class=\"o\">:=<\/span><span class=\"x\"> <\/span><span class=\"k\">range<\/span><span class=\"x\"> <\/span><span class=\"n\">values<\/span><span class=\"p\">[<\/span><span class=\"o\">:<\/span><span class=\"p\">]<\/span><span class=\"x\"> <\/span><span class=\"p\">{<\/span><span class=\"x\">\n        <\/span><span class=\"n\">sum<\/span><span class=\"x\"> <\/span><span class=\"o\">=<\/span><span class=\"x\"> <\/span><span class=\"n\">sum<\/span><span class=\"x\"> <\/span><span class=\"o\">+<\/span><span class=\"x\">  <\/span><span class=\"n\">v<\/span><span class=\"o\">*<\/span><span class=\"n\">v<\/span><span class=\"x\">\n    <\/span><span class=\"p\">}<\/span><span class=\"x\">\n<\/span><\/code><\/pre><\/div><\/div>\n\n<h3 id=\"go-for-loop-37-milliseconds\">Go for loop 37 milliseconds<\/h3>\n<div class=\"language-go highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"x\">    <\/span><span class=\"n\">sum<\/span><span class=\"x\"> <\/span><span class=\"o\">:=<\/span><span class=\"x\"> <\/span><span class=\"m\">0.0<\/span><span class=\"x\">\n    <\/span><span class=\"k\">for<\/span><span class=\"x\"> <\/span><span class=\"n\">i<\/span><span class=\"x\"> <\/span><span class=\"o\">:=<\/span><span class=\"x\"> <\/span><span class=\"m\">0<\/span><span class=\"p\">;<\/span><span class=\"x\"> <\/span><span class=\"n\">i<\/span><span class=\"x\"> <\/span><span class=\"o\">&lt;<\/span><span class=\"x\"> <\/span><span class=\"nb\">len<\/span><span class=\"p\">(<\/span><span class=\"n\">values<\/span><span class=\"p\">);<\/span><span class=\"x\"> <\/span><span class=\"n\">i<\/span><span class=\"o\">++<\/span><span class=\"x\"> <\/span><span class=\"p\">{<\/span><span class=\"x\">\n        <\/span><span class=\"n\">x<\/span><span class=\"x\"> <\/span><span class=\"o\">:=<\/span><span class=\"x\"> <\/span><span class=\"n\">values<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span><span class=\"x\">\n        <\/span><span class=\"n\">sum<\/span><span class=\"x\"> <\/span><span class=\"o\">=<\/span><span class=\"x\"> <\/span><span class=\"n\">sum<\/span><span class=\"x\"> <\/span><span class=\"o\">+<\/span><span class=\"x\">  <\/span><span class=\"n\">x<\/span><span class=\"o\">*<\/span><span class=\"n\">x<\/span><span class=\"x\">\n    <\/span><span class=\"p\">}<\/span><span class=\"x\">\n<\/span><\/code><\/pre><\/div><\/div>\n\n<p>Go has good performance with the both the usual imperative loop and their \u2018range\u2019 idiom which is like a \u2018foreach\u2019 in other languages. <br \/>\nNeither auto vectorization nor explicit SIMD support  appears to be completely not on the Go radar.  There are no map\/reduce\/fold higher order functions \nin the standard library, so we can\u2019t compare them.  Go does a good thing here by not providing a slow path at all.<\/p>\n\n<h3 id=\"conclusion\">Conclusion<\/h3>\n\n<p>I have shown some performance pitfalls in various languages here.  One should not read too much into this as an argument for general performance of these languages.\nEvery language has some pitfalls where the preferred or easiest approaches to solving a problem can lead to performance pitfalls. \nIn Java, for instance, everything is objects. Objects all allocate on the heap (unless the JIT does some work at runtime to determine it doesn\u2019t \nneed to go on the heap, but that isn\u2019t a freebie).  Since Java is also a garbage collected language, this can lead to performance pitfalls when\nyou type the obvious code.  With experience, you can learn about these pitfalls and do work to avoid them, just like you can avoid pitfalls of Linq in C#, by not using it, \nor the pitfalls of F# by using Stream or SIMD libraries instead of the core ones.  But even then, you have to take extra care, and type extra code, or take on more \ndependencies to do that.  This is partially purpose defeating, since high level languages are supposed to let you type less, and get things working faster.<\/p>\n\n<p>What I would like to see is more of an attitude change among high level language designers and their communities.  None of the issues above need to exist.\nJava could (and will, soon) provide value types (as C# does) to make it less painful to avoid GC pressure if you use lots of small, short lived constructs. Go\ncould provide more SIMD support, either via a SIMD library or better auto vectorization. F# could provide efficient Streams as part of the core library like Java does. \n .NET could auto vectorize  in the JIT and\/or provide more complete coverage of SIMD instructions in the Vector library.  We, the community, can help by providing libraries \nand <a href=\"https:\/\/jackmott.github.io\/programming\/2016\/08\/13\/adventures-in-fsharp.html\">submitting PRs<\/a> to make the obvious code faster.  Time and energy will be saved, \nbatteries will last longer, users will be happier.<\/p>\n\n<h3 id=\"benchmark-details-\">Benchmark Details <a name=\"benchmark\"><\/a><\/h3>\n\n<p>All benchmarks run with what I believe to be the latest and greatest compilers available for Windows for each language. JIT warmup time is accounted for when\napplicable. If you identify cases where code or compiler\/environment choices are sub optimal, email me please.<\/p>\n\n<h4 id=\"environment\">Environment<\/h4>\n<div class=\"language-ini highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"err\">Host<\/span> <span class=\"err\">Process<\/span> <span class=\"err\">Environment<\/span> <span class=\"err\">Information:<\/span>\n<span class=\"py\">BenchmarkDotNet<\/span><span class=\"p\">=<\/span><span class=\"s\">v0.9.8.0<\/span>\n<span class=\"py\">OS<\/span><span class=\"p\">=<\/span><span class=\"s\">Microsoft Windows NT 6.2.9200.0<\/span>\n<span class=\"py\">Processor<\/span><span class=\"p\">=<\/span><span class=\"s\">Intel(R) Core(TM) i7-4712HQ CPU 2.30GHz, ProcessorCount=8<\/span>\n<span class=\"py\">Frequency<\/span><span class=\"p\">=<\/span><span class=\"s\">2240907 ticks, Resolution=446.2479 ns, Timer=TSC<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h4 id=\"f--c-runtime-details\">F# \/ C# Runtime Details<\/h4>\n<div class=\"language-ini highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"py\">CLR<\/span><span class=\"p\">=<\/span><span class=\"s\">MS.NET 4.0.30319.42000, Arch=64-bit RELEASE [RyuJIT]<\/span>\n<span class=\"py\">GC<\/span><span class=\"p\">=<\/span><span class=\"s\">Concurrent Workstation<\/span>\n<span class=\"py\">JitModules<\/span><span class=\"p\">=<\/span><span class=\"s\">clrjit-v4.6.1590.0<\/span>\n<span class=\"py\">Type<\/span><span class=\"p\">=<\/span><span class=\"s\">SIMDBenchmark  Mode=Throughput  Platform=X64  <\/span>\n<span class=\"py\">Jit<\/span><span class=\"p\">=<\/span><span class=\"s\">RyuJit  GarbageCollection=Concurrent Workstation  <\/span>\n\n<\/code><\/pre><\/div><\/div>\n\n<h3 id=\"c-details\">C Details<\/h3>\n<p>Visual Studio 2015 Update 3, fast floating point, 64 bit, AVX2 instructions enabled, all speed optimizations on<\/p>\n\n<h3 id=\"rust-details\">Rust Details<\/h3>\n<p>v1.13 Nightly, \u2013release -opt-level=3<\/p>\n\n<h3 id=\"javascriptnode-details\">Javascript\/Node Details<\/h3>\n<p>v6.4.0 64bit\nNODE_ENV=production<\/p>\n\n<h3 id=\"java-details\">Java Details<\/h3>\n<p>Oracle Java 64bit version 8 update 102<\/p>\n\n<h3 id=\"go-details\">Go Details<\/h3>\n<p>Go 1.7<\/p>\n","pubDate":"Fri, 22 Jul 2016 19:17:27 +0000","link":"https:\/\/jackmott.github.io\/\/programming\/2016\/07\/22\/making-obvious-fast.html","guid":"https:\/\/jackmott.github.io\/\/programming\/2016\/07\/22\/making-obvious-fast.html","category":"programming"},{"title":"De-Cruft Visual Studio","description":"<p><img src=\"\/images\/vs-cruft.png\" alt=\"VS-Cruft\" title=\"VS Cruft\" \/>\nAbove is a screen shot of what Visual Studio looks like on most people\u2019s desktops.  There is a <em>lot<\/em> going on, and some people like it that way. They have a large monitor, \nthey use all of these features, and they suffer no performance and stability problems.  Some of us however, are really only interested in seeing the code, and find the rest\nof this to be a distraction that eats system resources and screen real estate. I will quickly explain how you can turn off any of these visual features that you do not actually want.\nThis can free you from visual distractions, or open up screen real estate to make side by side code editing a more practical endeavour. It may even reduce system resource use and \nimprove stability somewhat. (citation needed).  These tips all assume you are using Visual Studio 2015, though some may work on older versions as well.<\/p>\n\n<h3 id=\"remove-any-extensions-you-dont-use\">Remove any extensions you don\u2019t use<\/h3>\n\n<p>Often times performance and stability issues with Visual Studio 2015 are due to extensions.  Take a quick glance at your installed extensions by navigating to Tools-&gt;Extensions and Updates-&gt;Installed \nand see if there is anything there that you never actually use. If so, uninstall it.  If you have used ReSharper for a long time, Visual Studio has slowly been adding a lot of the features \nthat ReSharper used to add.  If you don\u2019t need ReSharper, you can get huge improvements in responsiveness by uninstalling it.<\/p>\n\n<h3 id=\"disable-codelens\">Disable CodeLens<\/h3>\n\n<p>The CodeLens feature of Visual Studio can be quite useful, it can display various meta-data about your code, and it\u2019s state within the context of your source control.  But if you do not\nmake use of it often, you can save a great deal of visual clutter, and perhaps improve the resource utilization and responsiveness of Visual Studio as well by turning it off.  You can\ndisable it globally at Tools-&gt;Options-&gt;Text Editor-&gt;All Languages, or on a per-language basis if you prefer.<\/p>\n\n<h3 id=\"solution-explorer-and-output--error-panes\">Solution Explorer and Output \/ Error Panes<\/h3>\n\n<p><img src=\"\/images\/vs-solution-explore.gif\" alt=\"VS-AutoHide\" title=\"VS AutoHide\" \/><\/p>\n\n<p>These are very commonly used tools, but you can have your cake and eat it too with them. At the top of these panels you will see a thumb-tack icon. You can click that to toggle \u2018Auto-Hide\u2019.\nWith \u2018Auto-Hide\u2019 enabled the panes will normally stay minified, but you can bring them up and put the focus in them with shortcut keys (CNTRL-ALT-L for solution explorer, \nCNTRL-ALT-O for Output, etc.)  and then you can hop back to your code with the ESC key.  While they are open, the focus will be in the pane and you can navigate them with the ARROW and ENTER keys,\nno need for the mouse.  This is a great way to free up space, and maintain the usefulness of the solution explorer.<\/p>\n\n<h3 id=\"hide-the-navigation-bar-and-code-outlining\">Hide The Navigation Bar and Code Outlining<\/h3>\n\n<p>Tools-&gt;Options-&gt;Text Editor-&gt;All Languages-&gt;General will give you the option to turn off the Navigation bar, a thin bar with dropdowns that notify you of the current method you are in.\nSome people like this feature, if you never use it, free up the space and turn it off.  You can turn if on\/off on a per language basis as well.  I also like to actually turn line numbers\non here.<\/p>\n\n<p>Hiding the code outlining graphics, if you find those useless, is a bit more tricky.  For some languages like C++ and C#, you can turn the feature off from within the language specific\noptions under Text Editor.  For others, like Javascript, you have to turn it off by hand on each file with CNTRL-M CNTRL-P<\/p>\n\n<h3 id=\"reduce-the-margins\">Reduce the Margins<\/h3>\n\n<p>By default there is a lot of horizontal space taken up by the Selection and Indicator margins.  If you don\u2019t make use of these, you can go\nto Tools-&gt;Options-&gt;Text Editor-&gt;General and unselect them both.<\/p>\n\n<h3 id=\"cleaning-up-the-menu-bar\">Cleaning up the Menu Bar<\/h3>\n\n<p>If you have been learning your keyboard shortcuts, the icons under the menu bar should be completely useless to you, and you can remove them by right clicking empty space in that area\nand deselecting any icon groups you don\u2019t need.  This can quickly free up vertical space.  You can go even further, and hide the menu text as well with extensions like \u2018Hide Main Menu\u2019. \nYou can still use the menu, as pressing the ALT key brings it back up. Just go to Tools-&gt;Extensions and Updates-&gt;Online and search for \u2018Hide Main Menu\u2019<\/p>\n\n<h3 id=\"full-screen\">Full Screen<\/h3>\n\n<p>Tap ALT-SHIFT-ENTER to go into fullscreen mode, this frees up some space as the window borders go away. This also makes the icons under the menu go away.<\/p>\n\n<h3 id=\"tab-group-jumper\">Tab Group Jumper<\/h3>\n\n<p>More of a productivity improvement than a de-crufting, but once you free up all this space, you may find you have room for 2 or 3 pages of code side by side.\nUnfortunately visual studio provides no way to jump between tab groups without the mouse.  The Tab Group Jumper extension adds this functionality. Tools-&gt;Extensions and Updates-&gt;Online\nand search for \u2018Tab Jumper\u2019<\/p>\n\n<h3 id=\"after-de-crufting\">After De-Crufting<\/h3>\n\n<p><img src=\"\/images\/vs-nocruft.png\" alt=\"VS-NoCruft\" title=\"VS NoCruft\" \/><\/p>\n\n<p>Now with space freed up, you have more room on your screen for code, side by side editing, or whatever else you desire.<\/p>\n","pubDate":"Mon, 11 Jul 2016 19:17:27 +0000","link":"https:\/\/jackmott.github.io\/\/programming\/tools\/editor\/ide\/visual\/studio\/2016\/07\/11\/decruft-visual-studio.html","guid":"https:\/\/jackmott.github.io\/\/programming\/tools\/editor\/ide\/visual\/studio\/2016\/07\/11\/decruft-visual-studio.html","category":["programming","tools","editor","ide","visual","studio"]},{"title":"Marginal Gains","description":"<p>In a former life I was heavily involved in bike racing, and became obsessed with the concept of \u201cmarginal gains\u201d. It is the idea that there exist a multitude of choices you can make, \neach of which, in isolation, has little to no effect on your result, but in totality can be the difference between success and failure.  It is a philosophy which requires a delicate balance.\nToo much time spent worrying about minutiae can distract from the business of actually training. But ignoring marginal gains completely means you will eventually lose to someone\nwho did not.<\/p>\n\n<p>So it is with being a software developer. Taking time to master your tools will save you time, and expand your abilities. But, at some point, you just need to shut up and code.<\/p>\n\n<h2 id=\"become-one-with-the-command-line\">Become one with the command line<\/h2>\n\n<p>If you spend most of your time in Windows software development it is possible to get by and never really master various command line systems and tools.  Taking the time to force yourself to\nlearn these things can be extremely valuable and open up entirely new worlds.  Being familiar with how to get things building from source in Linux for example, can allow you to\nleverage and contribute to open source projects that might otherwise be unavailable to you.  If your projects are deployed to cloud infrastructures such as Azure or AWS, being \nable to manage all of that from Bash or Powershell let\u2019s you get things done much, much faster than working through web GUI interfaces.  You will likely be able to easily automate a lot\nof your daily tasks with scripts.  For instance do you type \u201cgit add *, git commit -m \u201cfoo\u201d, git push\u201d 30 times a day? (or use your mouse and click through 3 menus in the GUI equivalent?) \nThat is an easy fix for even a beginner at bash or batch file scripting.\nBeing familiar with the command line also opens up options such as using faster or more flexible code editors, rather than being stuck in Visual Studio, Eclipse, etc because you\ndon\u2019t understand how to build and run things without the IDE to help you. The possibilities here are too many to list.  Take stock of the kinds of things you work on, and take time out \nof your day to learn Bash, or Powershell, or whatever command line skills may be relevant to your job and interests.<\/p>\n\n<h2 id=\"master-your-code-editors\">Master your code editors<\/h2>\n\n<p>Whatever you use to edit code, whether it be an IDE like Visual Studio or a text editor like VIM or Sublime, take some time to truly master it.  Think carefully about what wastes your\ntime as you use it.  Do you spend lots of time navigating around code with the arrow keys?  Learn what shortcuts are available to speed that up.  Move to next token, move to next \/ previous\nmatching brace, these are often features available with a hotkey in a good editor.  If you want a feature that isn\u2019t there, look into customizing the editor to add it. Occasionally take a day \nand make it a goal to do all your coding without touching the mouse.  At first you will find hundreds of things you can\u2019t accomplish without doing so, but gradually you will learn how to\nbring that down to zero, either by learning keyboard shortcuts, or tweaking your environment so you don\u2019t need them. Here are some common examples:<\/p>\n\n<h3 id=\"changing-indentation-on-blocks\">Changing indentation on blocks<\/h3>\n<p><img src=\"\/images\/tab-1.gif\" alt=\"tab-1\" title=\"Tab Slow\" \/> <img src=\"\/images\/tab-2.gif\" alt=\"tab-2\" title=\"Tab Fast\" \/><\/p>\n\n<p>With Visual Studio you can do this by selecting and using TAB and SHIFT-TAB. You can even select rectangular regions with ALT-SHIFT-ARROWS.<\/p>\n\n<h3 id=\"token-delete-and-multi-line-editing\">Token Delete and Multi Line Editing<\/h3>\n<p><img src=\"\/images\/token-1.gif\" alt=\"token-1\" title=\"Token Slow\" \/> <img src=\"\/images\/token-2.gif\" alt=\"token-2\" title=\"Token Faster\" \/> <img src=\"\/images\/token-3.gif\" alt=\"token-3\" title=\"Token Fastest\" \/><\/p>\n\n<p>In Visual Studio you can delete entire tokens at a time with CNTRL-DEL or CNTRL-BACKSPACE. You can also navigate the cursor a token at a time with CNTRL-ARROW. Some may find it useful to also\nhave a camelcase\/pascalcase aware feature.  The third gif here shows Multi Line editing in action, where you can use the ALT-SHIFT selection feature and make identical changes to \nmany lines at once. Most code editors will have a feature like this, it can be very useful to learn it.<\/p>\n\n<p>There are dozens of little tricks like this available in any decent code editor. Any time you find yourself having to bang a lot of keys or use the mouse to get things done, investigate whether\nyour editor has a shortcut built in for the task, or whether you can easily add one. These will take practice to use quickly and without thinking about it, but when you build up a nice set \nof shortcuts, such that you are rarely touching the mouse or repeating keystrokes, you will get things done faster, and more pleasantly.<\/p>\n\n<p>A few more freebies in Visual Studio:<\/p>\n\n<ul>\n  <li>F9 set\/unset a breakpoint on the current line<\/li>\n  <li>F12 go to definition of the token the cursor is currently on<\/li>\n  <li>F5 to run  SHIFT-F5 to stop the current default project<\/li>\n  <li>CNTRL-TAB to pop to the previously focused window<\/li>\n  <li>Hold CNTRL and press TAB to cycle through all previously open windows<\/li>\n  <li>CNTRL-K CNTRL-O in C++ files to hop between .h\/.hpp and .cpp\/.c files<\/li>\n  <li>CNTRL-ALT-L to pop to the solution explorer, ARROWS and ENTER to navigate\/open<\/li>\n<\/ul>\n\n<h2 id=\"expand-either-the-depth-or-breadth-of-your-skills\">Expand either the depth, or breadth, of your skills<\/h2>\n\n<p>Take some time to Git Gud.  Maybe you are committed to being deeply expert in one aspect of programming. If so, take time to deepen your understanding.  Think about what language features or \nprogramming concepts have confused you in the past.  Set time aside to master those things.<\/p>\n\n<p>Alternatively, especially if you are younger, take time to learn and practice entirely new philosophies.  Has your career to date been entirely in managed runtimes? Start a personal project in C,\nD, or Rust, and learn what programming without garbage collection, and with access to the bare metal is like.  Have you done nothing but Object Oriented Programming your whole life? \nTry some side projects in a functional language, and try it again in ANSI C.  Learn for yourself what the pros and cons of these paradigms are for you.  Do not believe the assertions you\nhear every day about different programming paradigms, almost none of them are backed up with rigorous evidence.  Take time to investigate \nthe universes you are not familiar with. Consider contributing to an open source project, where you can learn from a new set of people than you deal with at your day job.  You will likely\npick up useful tips and techniques from that that you can use elsewhere. Even if you end up sticking with what you already know, you will likely learn some things to make you better at that too.<\/p>\n\n","pubDate":"Fri, 01 Jul 2016 19:17:27 +0000","link":"https:\/\/jackmott.github.io\/\/programming\/tools\/editor\/ide\/visual\/studio\/2016\/07\/01\/marginal-gains.html","guid":"https:\/\/jackmott.github.io\/\/programming\/tools\/editor\/ide\/visual\/studio\/2016\/07\/01\/marginal-gains.html","category":["programming","tools","editor","ide","visual","studio"]}]}}