tag:blogger.com,1999:blog-76236408727360890682024-03-13T13:47:43.871+03:00vaskir's blogVasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.comBlogger87125tag:blogger.com,1999:blog-7623640872736089068.post-70957462415898187872021-12-22T18:08:00.002+03:002021-12-22T18:08:47.701+03:00How Go runtime makes concurrent code simple5 years ago I showed a way to fight with "all-threads-busy" problem <a href="http://vaskir.blogspot.com/2016/06/running-computational-intensive-code.html" target="_blank">while writing Hopac code</a>. The same problem exists on JVM as well. The root is in the cooperative concurrency model, which is based on thread pools, async/futures/etc. are scheduled to run on them. So, if an async is blocked by an IO call of if it's just executing some computation, the OS thread is not able to do anything else: the scheduler is unable to "pause" such a blocked async and execute anothe one. So, asynchronous code on .NET, JVM, Rust, etc. is inherently unsafe: it's not guaranteed that all existing asyncs progress.
<p>
The things are different in Go runtime: the scheduler is preemptive, so it can "pause" goroutines at any point: not only at function calls, at loops, but on just any execution point (almost). This makes writing concurrent code dead easy: there's no "async" functions, lambdas or blocks of code, every function or call are the same, being them executed in "main" thead or in a goroutine.
<p>
Let's look at the mention above code being written in Go:
<p>
<script src="https://gist.github.com/vasily-kirichenko/da57c3284220349fc04f54000278faf3.js"></script>
<p>
No <i>let!</i>, <i>await</i>, <i>async</i>, <i>do!</i>, <i>StartAsTask</i>, <i>match!</i> and so on. Need to run some code concurrently? Add <i>go</i> keyword. Done. Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com0tag:blogger.com,1999:blog-7623640872736089068.post-57143864339923936472016-08-13T18:28:00.002+03:002016-08-13T22:48:06.789+03:00Load balancing: Rancher vs Swarm<div dir="ltr" style="text-align: left;" trbidi="on">
Rancher has a load balancer built it (HAProxy). Let's compare its performance vs Docker Swarm one. I will use 3 identical nodes:<br />
<br />
<ul style="text-align: left;">
<li>192GB RAM</li>
<li>28-cores i5 Xeon</li>
<li>1GBit LAN</li>
<li>CentOS 7</li>
<li>Docker 1.12</li>
<li>Rancher 1.1.2</li>
</ul>
<div>
I will benchmark against a hello world HTTP server written in Scala with Akka-HTTP and Spray JSON serialization (I don't think it matters though), sources are <a href="https://github.com/vasily-kirichenko/AkkaHttp1">on GitHub</a>. I will use Apache AB benchmark tool.</div>
<div>
<br /></div>
<div>
As a baseline, I exposed the web server port outside the container and run the following command:</div>
<div>
<br /></div>
<div>
ab -n 100000 -c 20 -k http://1.1.1.1:29001/person/kot</div>
<div>
<br /></div>
<div>
It shows 22400 requests per second. I'm not sure whether it's a great result for Akka-HTTP, considering that some services written in C can handle hundreds of thousands requests per second, but it's not the main topic of this blog post (I ran the test with 100 concurrent connections (-c 100), and it shows ~50k req/sec. I don't know if this number is good enough either :) )</div>
<div>
<br /></div>
<div>
Now I created a Rancher so-called "stack" containing our web server and a build in load balancer:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-nCxlFjGQY_c/V684y65g4HI/AAAAAAAAMNs/DLGdUol008YBn-1BYmAG3EsJqoErukGXwCLcB/s1600/Untitled.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="123" src="https://4.bp.blogspot.com/-nCxlFjGQY_c/V684y65g4HI/AAAAAAAAMNs/DLGdUol008YBn-1BYmAG3EsJqoErukGXwCLcB/s640/Untitled.png" width="640" /></a></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div>
<br /></div>
<div>
Now run the same benchmark against the load balancer, increasing number of akka-http containers one-by-one:</div>
<div>
<br /></div>
<div>
</div>
<br />
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; width: 167px;">
<colgroup><col style="width: 51pt;" width="68"></col>
<col style="mso-width-alt: 3379; mso-width-source: userset; width: 74pt;" width="99"></col>
</colgroup><tbody>
<tr height="19" style="height: 14.25pt;">
<td height="19" style="height: 14.25pt; width: 51pt;" width="68">Containers</td>
<td style="width: 74pt;" width="99">Req/sec</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td align="right" height="19" style="height: 14.25pt;">1</td>
<td align="right">755</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td align="right" height="19" style="height: 14.25pt;">2</td>
<td align="right">1490</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td align="right" height="19" style="height: 14.25pt;">3</td>
<td align="right">2200</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td align="right" height="19" style="height: 14.25pt;">4</td>
<td align="right">3110</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td align="right" height="19" style="height: 14.25pt;">5</td>
<td align="right">3990</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td align="right" height="19" style="height: 14.25pt;">6</td>
<td align="right">4560</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td align="right" height="19" style="height: 14.25pt;">7</td>
<td align="right">4745</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td align="right" height="19" style="height: 14.25pt;">8</td>
<td align="right">4828</td>
</tr>
</tbody></table>
<br />
<div>
OK, it looks like HAProxy introduced a lot of overhead. Let's look how well Swarm internal load balancer handles such load. After initializing Swarm on all nodes, create a service:</div>
<div>
<br /></div>
<div>
docker service create --name akka-http --publish 32020:29001/tcp private-repository:5000/akkahttp1:1.11</div>
<div>
<br /></div>
<div>
Check that the container is running:</div>
<div>
<br /></div>
<div>
$ docker service ps akka-http</div>
<div>
0yb99vo9btmx3t1wluvd0fgo6 akka-http.1 1.1.1.1:5000/akkahttp1:1.11 xxxx Running Running 3 minutes ago</div>
<div>
<br /></div>
<div>
OK, great. Now I will scale our service up one container at a time, running the same benchmark as I go:</div>
<div>
<br /></div>
<div>
docker service scale akka-http=2</div>
<div>
docker service scale akka-http=3</div>
<div>
...</div>
<div>
docker service scale akka-http=8</div>
<div>
<br /></div>
<div>
Results:</div>
<div>
<br /></div>
<div>
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; width: 167px;">
<colgroup><col style="width: 51pt;" width="68"></col>
<col style="mso-width-alt: 3379; mso-width-source: userset; width: 74pt;" width="99"></col>
</colgroup><tbody>
<tr height="19" style="height: 14.25pt;">
<td height="19" style="height: 14.25pt; width: 51pt;" width="68">Containers</td>
<td style="width: 51pt;" width="68">Req/sec</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td align="right" height="19" style="height: 14.25pt;">1</td>
<td align="right">19200</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td align="right" height="19" style="height: 14.25pt;">2</td>
<td align="right">19700</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td align="right" height="19" style="height: 14.25pt;">3</td>
<td align="right">18700</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td align="right" height="19" style="height: 14.25pt;">4</td>
<td align="right">18700</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td align="right" height="19" style="height: 14.25pt;">5</td>
<td align="right">18300</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td align="right" height="19" style="height: 14.25pt;">6</td>
<td align="right">18800</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td align="right" height="19" style="height: 14.25pt;">7</td>
<td align="right">17900</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td align="right" height="19" style="height: 14.25pt;">8</td>
<td align="right">18300</td>
</tr>
</tbody></table>
</div>
<div>
<br />
Much better! Swarm LB does introduce some little overhead, but it's totally tolerable. What's more, if I run the benchmark against the node where single container is running, Swarm LB shows exactly same performance as directly exposed web server (22400 req/sec in my case).<br />
<br />
To make this blog post less boring, I added a nice picture :)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-kyweBA-ukW4/V688PSwyH2I/AAAAAAAAMN4/W3mm61KIm0E0fsvYBsVmWXFj8HPCO-XRQCLcB/s1600/Screenshot_6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="418" src="https://4.bp.blogspot.com/-kyweBA-ukW4/V688PSwyH2I/AAAAAAAAMN4/W3mm61KIm0E0fsvYBsVmWXFj8HPCO-XRQCLcB/s640/Screenshot_6.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I run JMeter (8 parallel threads). Direct: 6700, Swarm: 6500 (1 container) - 5600 (8 containers), Rancher: 835 r/s (1 container) - 2400 (8 containers). Which is roughly the same as AB results. </div>
<br /></div>
</div>
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com0tag:blogger.com,1999:blog-7623640872736089068.post-37743552827011095542016-06-11T22:48:00.000+03:002016-06-11T22:48:46.917+03:00Running computational intensive code outside of Hopac scheduler<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="https://github.com/Hopac/Hopac">Hopac</a> uses a bounded pool of worker threads, number of which is equal to number of CPU cores (by default). A dangerous thing about this design is that a situation is possible where all the threads are busy doing some CPU intensive work and no other Hopac jobs can proceed. A good solution for this is running such a CPU bound computations on the standard .NET thread pool, freeing Hopac pool for more intelligent work. I found a nice code in one of the older <a href="https://github.com/Hopac/Hopac/issues/26#issuecomment-63172608">Hopac GitHub discussions</a> which schedules a ordinary function on ThreadPool and represents the result as a Hopac job.
<p>Here is a test with explanations:
<p>
<script src="https://gist.github.com/vasily-kirichenko/d6544f78f0c4a7a5794389c9877694d5.js"></script>
<p>
</div>
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com0tag:blogger.com,1999:blog-7623640872736089068.post-20188232352568541362016-05-27T20:21:00.001+03:002016-05-27T21:11:54.155+03:00Upcoming F# struct tuples: are they always faster?<div dir="ltr" style="text-align: left;" trbidi="on">
Don Syme <a href="https://github.com/Microsoft/visualfsharp/pull/1043">has been working</a> on struct tuples for F# language. Let's see if they are more performant than "old" (heap allocated) tuples in simple scenario: returning tuple from function. The code is very simple:
<p>
<script src="https://gist.github.com/vasily-kirichenko/a3bc6baa2fbcf5fbc062ab7c76b2a9be.js"></script>
<p>
Decompiled code in Release configuration:
<p>
<script src="https://gist.github.com/vasily-kirichenko/8ebe866cbdacf5bd46fb96c7c3b3def5.js"></script>
<p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-D9kQiWEJy3M/V0iGdfyKbEI/AAAAAAAAMGA/rpCylZbz5csvJFf37sPZlldJTaKKI7iHwCLcB/s1600/plane_tuples_allocations.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://2.bp.blogspot.com/-D9kQiWEJy3M/V0iGdfyKbEI/AAAAAAAAMGA/rpCylZbz5csvJFf37sPZlldJTaKKI7iHwCLcB/s640/plane_tuples_allocations.png" width="640" /></a></div>
<br />
<div>
<br /></div>
<p>
Everything we need to change to switch to struct tuples, is adding "struct" keyword in front of constructor and pattern matching:
<br />
<br />
<p>
<script src="https://gist.github.com/vasily-kirichenko/e92041ffa35b1eee272dab5794b36c4d.js"></script><br /><div>
<p>
Decompiled code in Release configuration:
<p>
<script src="https://gist.github.com/vasily-kirichenko/069f21f0a987b8573f9a15d3f0bb3fae.js"></script>
<p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-hbgqBeR8uyM/V0iGy1aiZzI/AAAAAAAAMGE/sy2hYIdat3kKiSAmz5edXGZMlMNgsD8twCLcB/s1600/struct_tuples_allocation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://3.bp.blogspot.com/-hbgqBeR8uyM/V0iGy1aiZzI/AAAAAAAAMGE/sy2hYIdat3kKiSAmz5edXGZMlMNgsD8twCLcB/s640/struct_tuples_allocation.png" width="640" /></a></div>
<p>
I don't know about you, but I was surprised with those results. The performance roughly the same. GC is not a bottleneck as no objects were promoted to generation 1.<br />
<br />
Conclusions:
<br />
<br />
<ul style="text-align: left;">
<li>Using struct tuples as a faster or "GC-friendly" alternative to return multiple values from functions does not make sense.</li>
<li>Building in release mode erases away heap allocated tuples, but not struct tuples.
<li>Building in release mode inlines the "foo" function, which makes the code 10x faster.
<li>You can fearlessly allocate tens of millions of short-living object per second, performance will be great.</li>
</ul>
<br />
<br />
</div>
</div>Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com9tag:blogger.com,1999:blog-7623640872736089068.post-67499109861155990132016-05-22T19:00:00.000+03:002016-05-30T21:36:54.507+03:00Hash maps: Rust, F#, D, Go, Scala<div dir="ltr" style="text-align: left;" trbidi="on">
Let's compare performance of hashmap implementation in Rust, .NET, D (LDC) and Go.<br />
Rust:
<br />
<script src="https://gist.github.com/vasily-kirichenko/8aaf42eea848ab2f0043f514c7fbbf22.js"></script>
F#:
<br />
<script src="https://gist.github.com/vasily-kirichenko/c577968f9ac90e0823f0ae7118c01a8f.js"></script>
As you can see, Rust is slower at about 17% on insersions and at about 21% on lookups.
<br />
<br />
<h3>
Update</h3>
As @GolDDranks <a href="https://twitter.com/GolDDranks/status/734466741103824896">suggested on Twitter</a>, since Rust 1.7 it's possible to use custom hashers in HashMap. Let's try it:
<br />
<script src="https://gist.github.com/vasily-kirichenko/7ba1a2cc1a49ead1bc49b55e8971dbe5.js"></script>
Yes, it's significantly faster: additions is only 5% slower than .NET implementation, and lookups are 32% *faster*! Great.
<br />
<br />
<h3>
Update: D added</h3>
<a href="https://github.com/ldc-developers/ldc/releases/download/LDC-Win64-master/LDC-master-1624-x64.7z">LDC x64 on windows</a>
<br />
<script src="https://gist.github.com/vasily-kirichenko/e143fc3487a3cef19ed1ec377c14cd11.js"></script>
It's very slow at insertions and quite fast on lookups.
<br />
<br />
<h3>
Update: Go added</h3>
<script src="https://gist.github.com/vasily-kirichenko/98ccff92f8529f51824cc9cf32ebf81a.js"></script>
<br />
<h3>
Update: Scala added</h3>
<script src="https://gist.github.com/vasily-kirichenko/f5afa4fcafa72cbb4d9fb3ae6bf2fd3c.js"></script>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-5Oy98Z2gATE/V0yIKeiTWMI/AAAAAAAAMIc/ZwpPfQwPiN4ugykIqonuKhGVBn7CcB6NACLcB/s1600/hash_maps_fsharp_d_rust_go_scala.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://4.bp.blogspot.com/-5Oy98Z2gATE/V0yIKeiTWMI/AAAAAAAAMIc/ZwpPfQwPiN4ugykIqonuKhGVBn7CcB6NACLcB/s640/hash_maps_fsharp_d_rust_go_scala.PNG" width="442" /></a></div>
<br />
Compared to Scala all the other languages looks equally fast :) What's worse, Scala loaded all four CPU cores at almost 100% during the test, while others used roughly single core. My guess is that JVM allocated so many objects (each Int is an object, BTW), that 3/4 of CPU time was spend for garbage collecting. However, I'm a Scala/JVM noob, so I just could write the whole benchmark in a wrong way. Scala developers, please review the code and explain why it's so slow (full IDEA/SBT project is <a href="https://github.com/vasily-kirichenko/ScalaHashMapTest">here</a>). Thanks!
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
</div>
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com9tag:blogger.com,1999:blog-7623640872736089068.post-88159763496904462202016-05-04T14:30:00.001+03:002016-05-09T12:07:33.417+03:00Akka.NET Streams vs Hopac vs AsyncSeq<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="https://github.com/akkadotnet/akka.net/tree/akka-streams">Akka.NET Streams</a> is a port of its Scala/Java counterpart and intended to execute complex data processing graphs, optionally in parallel and even distributed. It has quite different semantics compared to Hopac's one and it's wrong to compare them feature-by-feature, but it's still interesting to benchmark them in a scenario which both of them supports well: read lines of a file asynchronously, filter them by a regex in controlled degree of parallelism, then normalize the lines with a simple string manipulation algorithm, also in parallel, then count the number of lines.<br />
<br />
Firts, Akka.NET:<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/55ba97032c6a89c0e1ed78e3940a38ca.js"></script>
Note that I have to use the empty string as indication that the regular expression does not match. I should use `option<string>` of course (just like I do in the Hopac snippet below), but Akka.NET Streams is strict about what is allowed to be returned by its combinators like `Map` or `Filter`, in particular, you cannot return `null`, doing so makes Akka.NET unhappy and it will throw exception at you. In F#, expressions like `fun x -> printfn "%O" x` and `fun x -> None` returns `()` and `None` values respectively, which are represented as `null` at runtime, so you have to be very careful `Map`ping and `Filter`ing (and using all the combinators actually) over side effecting functions or returning `Options` (just do not do either).
</string>
<p>
Now, Hopac:<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/626f570188ba26921e86fc013a583b55.js"></script>
And finally AsyncSeq:
<p>
<script src="https://gist.github.com/vasily-kirichenko/168e9b045b1d152bed907ec5840ad5d5.js"></script>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/--6TzDM4l75Y/VzBQ6aOF1DI/AAAAAAAAL-M/x8Xi2GcPRS4jrndlPresAtlHLkB1szCHgCLcB/s1600/hopac_akka_net_async_seq_bench.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://3.bp.blogspot.com/--6TzDM4l75Y/VzBQ6aOF1DI/AAAAAAAAL-M/x8Xi2GcPRS4jrndlPresAtlHLkB1szCHgCLcB/s400/hopac_akka_net_async_seq_bench.PNG" width="307" /></a></div>
<br />
Number of allocations is roughly identical for Hopac and Akka, but it's an order of magnitude larger for AsyncSeq.<br />
<br />
<h3>
Conclusions</h3>
<ul>
<li>Use Hopac if you need the best performance available on .NET, or if you need to implement arbitrary complex concurrent scenarios.
</li>
<li>Akka.NET is quite fast and has a full blown graph definition DSL, so it's great for implementing complex stream processing, which can run on a cluster of nodes. However, it has a typical "fluent" C#-targeted API, so it's necessary to write a thin layer over it in order to make it usable from F#.
</li>
<li>AsyncSeq has the most "F# friendly" API - it's just a combination of two computation expressions which every F# programmer knows: Async and Seq.</li>
</ul>
<h3>
</h3>
<h3>
Update 6 May, 2016</h3>
<div>
<br /></div>
Marc Piechura suggested a way to exclude materialization phase from the benchmark, here is the modified code:
<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/f671e343b4c555943d3db94cebce20de.js"></script>
It turns out it takes Akka.NET about 3 seconds to materialize the graph.<br />
<br />
Thanks Vesa Karvoven for help with fixing the Hopac version and Lev Gorodinski for fixing AsyncSeq performance (initially it works awfully slow).
</div>Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com12tag:blogger.com,1999:blog-7623640872736089068.post-8417768162542641082015-09-24T18:45:00.002+03:002017-12-03T18:47:22.374+03:00Regular expressions: Rust vs F# vs Scala<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
Let's implement the following task: read first 10M lines from a text file of the following format:<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/08a1f76d3d5cc497110d.js"></script>
</div>
then find all lines containing Microsoft namespace in them, and format the type names the usual way, like "Microsoft.Win32.IAssemblyEnum".<br />
<br />
First, F#:<br />
<br /></div>
<script src="https://gist.github.com/vasily-kirichenko/2bb850c3dfcfaad71d36.js"></script>
Now Rust:<br />
<br /></div>
<script src="https://gist.github.com/vasily-kirichenko/ac68a41a5d0166b8bd56.js"></script>After several launches the file was cached by the OS and both implementations became non IO-bound. F# one took 29 seconds and 31MB of RAM at peak; Rust - 11 seconds and 18MB.<br />
<br />
The Rust code is as twice as long as F# one, but it's handling all possible errors explicitly - no surprises at runtime at all. The F# code may throw some exceptions (who knows what kind of them? Nobody). It's possible to wrap all calls to .NET framework with `Choice.attempt (fun _ -> ...)`, then define custom Error types for regex related code, for IO one and a top-level one, and the code'd be even longer then Rust's, hard to read and it would still give no guarantee that we catch all possible exceptions.<br />
<br />
<b>Update 4 Jan 2016</b>: Scala added:<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/172f373591bc3f028398.js"></script>
Ok, it turns out that regex performance may depend on whether it's case sensitive or not. What's worse, I tested F# with case insensitive pattern, but Rust - for case sensitive. Anyway, as I've upgraded my machine recently (i5-750 => i7-4790K), I've rerun F# and Rust versions in both the regex modes and added Scala to the mix. First, case sensitive mode:<br />
<ul style="text-align: left;">
<li>F# (F# 4.0, .NET 4.6.1) - 4.8 secs</li>
<li>Scala (2.11.7, Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_65) - 3.5 secs</li>
<li>Rust (1.7.0-nightly (bfb4212ee 2016-01-01) - 5.9 secs</li>
</ul>
<div>
Now, case insensitive:<br />
<ul>
<li>F# (F# 4.0, .NET 4.6.1) - 15.5 secs</li>
<li>Scala (2.11.7, Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_65) - 3.2 secs</li>
<li>Rust (1.7.0-nightly (bfb4212ee 2016-01-01) - 6.1 secs</li>
</ul>
<br />
Although case sensitive patterns performs roughly the same on all the platforms, it's quite surprising that Rust is not the winner.<br />
<br />
Scala is faster in case insensitive mode (?), Rust is slightly slower and now the question: what's wrong with .NET implementation?.. It performs more than 3 times slower that case sensitive and the others.<br />
<br />
<b>Update 4 Jan 2016</b>: D added.<br />
<br /></div>
<div>
<script src="https://gist.github.com/vasily-kirichenko/8b10d37615aabaf188bf.js"></script>
</div>
<br />
<ul style="text-align: left;">
<li>regex - 10.6 s (DMD), 7.8 s (LDC)</li>
<li>ctRegex! - 6.9 s (DMD), 6.6 s (LDC)</li>
</ul>
<div>
<b><br /></b>
<b>Update 6 Jan 2016</b>: Elixir added:</div>
<div>
<br /></div>
<div>
<script src="https://gist.github.com/vasily-kirichenko/5703644937a00531b194.js"></script>
</div>
It takes 56 seconds to finish.
<br />
<br />
<b>Update 6 Jan 2016</b>: Haskell added:<br />
<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/0fb88cf9c69af1a9f62f.js"></script>
I takes 20 seconds.
<br />
<br />
<b>Update 7 Jan 2016</b>: Nemerle added:<br />
<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/31a0b5c8e660eca15a87.js"></script>
It takes 3.8 seconds (case sensitive) and 7.1 seconds (case insensitive).
<br />
<br />
<b>Update 8 Jan 2016</b>: Nemerle PEG added:<br />
<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/0841ee9b37f43c843245.js"></script>
It takes 4.1 seconds.<br />
<br />
All results so far:<br />
<br />
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; width: 365px;">
<colgroup><col style="mso-width-alt: 3345; mso-width-source: userset; width: 74pt;" width="98"></col>
<col style="mso-width-alt: 4386; mso-width-source: userset; width: 96pt;" width="129"></col>
<col style="mso-width-alt: 4710; mso-width-source: userset; width: 104pt;" width="138"></col>
</colgroup><tbody>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="height: 14.25pt; width: 74pt;" width="98"></td>
<td class="xl66" style="border-left: none; width: 96pt;" width="129">Case sensitive</td>
<td class="xl66" style="border-left: none; width: 104pt;" width="138">Case
insensitive</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">F#</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">4,80</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">15,50</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">Scala</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">3,50</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">3,20</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">Rust</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">5,90</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">6,10</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">DMD</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">6,90</td>
<td class="xl65" style="border-left: none; border-top: none;"></td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">LDC</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">6,60</td>
<td class="xl65" style="border-left: none; border-top: none;"></td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">Elixir</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">56,00</td>
<td class="xl65" style="border-left: none; border-top: none;"></td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">Hakell</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">20,00</td>
<td class="xl65" style="border-left: none; border-top: none;"></td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">Nemerle</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">3,80</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">7,10</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">Nemerle PEG</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">4,10</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">4,20</td>
</tr>
</tbody></table>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-pcLk1Gr7XA0/Vo-eZoWzDLI/AAAAAAAALyY/8AtN36UB0Uk/s1600/big_file_parse.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /><img alt="" border="0" height="481" src="https://1.bp.blogspot.com/-pcLk1Gr7XA0/Vo-eZoWzDLI/AAAAAAAALyY/8AtN36UB0Uk/s640/big_file_parse.PNG" title="" width="640" /></a></div>
<br />
<b>Update 3 Dec 2017</b>: Rust's regex crate updated and code cleanup, F# run on .NET Core 2.0:<br />
<br />
<h4>F#</h4>
<script src="https://gist.github.com/vasily-kirichenko/2c3da667178c693a8cb5a39cfd34f3f6.js"></script>
<br />
<h4>Rust</h4>
<script src="https://gist.github.com/vasily-kirichenko/d88a15d62c19b87042c937136896bcb2.js"></script>
<br />
Rust version now performs 2x faster, F# is slower on case sensitive and faster on case insensitive on Core:<br />
<br />
All results so far:<br />
<br />
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; width: 365px;"><colgroup><col style="mso-width-alt: 3345; mso-width-source: userset; width: 74pt;" width="98"></col>
<col style="mso-width-alt: 4386; mso-width-source: userset; width: 96pt;" width="129"></col>
<col style="mso-width-alt: 4710; mso-width-source: userset; width: 104pt;" width="138"></col>
</colgroup><tbody>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="height: 14.25pt; width: 74pt;" width="98"><br /></td>
<td class="xl66" style="border-left: none; width: 96pt;" width="129">Case sensitive</td>
<td class="xl66" style="border-left: none; width: 104pt;" width="138">Case
insensitive</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">F#</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">6,57</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">9,56</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">Scala</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">3,50</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">3,20</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">Rust</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">2,97</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">3,02</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">DMD</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">6,90</td>
<td class="xl65" style="border-left: none; border-top: none;"><br /></td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">LDC</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">6,60</td>
<td class="xl65" style="border-left: none; border-top: none;"><br /></td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">Elixir</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">56,00</td>
<td class="xl65" style="border-left: none; border-top: none;"><br /></td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">Hakell</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">20,00</td>
<td class="xl65" style="border-left: none; border-top: none;"><br /></td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">Nemerle</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">3,80</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">7,10</td>
</tr>
<tr height="19" style="height: 14.25pt;">
<td class="xl66" height="19" style="border-top: none; height: 14.25pt;">Nemerle PEG</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">4,10</td>
<td align="right" class="xl65" style="border-left: none; border-top: none;">4,20</td></tr>
</tbody></table>
<br />
I removed Elixir from the chart as it's a clear outsider and its results make the chart read harder: <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-MN-Jz_FfGqU/WiQab0FGpOI/AAAAAAAAPc0/NYEZtO5HreQplKwbaxuLv09Zey7oXzX4ACLcBGAs/s1600/regex-benchmark.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="993" data-original-width="1361" height="466" src="https://1.bp.blogspot.com/-MN-Jz_FfGqU/WiQab0FGpOI/AAAAAAAAPc0/NYEZtO5HreQplKwbaxuLv09Zey7oXzX4ACLcBGAs/s640/regex-benchmark.png" width="640" /></a></div>
</div>
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com25tag:blogger.com,1999:blog-7623640872736089068.post-44911882779245067692015-07-18T13:34:00.003+03:002015-07-18T13:34:33.129+03:00Elixir: first look<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
I don't have a clear impression about Elixir language yet. I don't like it has Ruby like syntax, but do like it has pipe operator and macros. So, Fibonacci:<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/05826016c34b1c6a4388.js"></script>
</div>
It executes in about 13 seconds which is on pair (even faster for unknown reason) with Erlang, no surprises here.<br />
<br />
<ul style="background-color: white; color: #666666; font-family: Georgia, Utopia, 'Palatino Linotype', Palatino, serif; font-size: 16.5px; line-height: 23.1000003814697px; margin: 0.5em 0px; padding: 0px 2.5em;">
<li style="margin: 0px 0px 0.25em; padding: 0px;">D (GDC) - 0.990</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">C# - 1.26</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 23.1000003814697px;">D (DMD) - 1.3</span></li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 23.1000003814697px;">C++ - 1.33</span></li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 23.1000003814697px;">F# - 1.38</span></li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Nemerle - 1.45</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 23.1000003814697px;">Rust - 1.66</span></li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Go - 2.38</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Haskell - 2.8</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 23.1000003814697px;">Clojure - 9</span></li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 23.1000003814697px;">Elixir - 13</span></li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Erlang - 17</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Ruby - 60</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Python - 120</li>
</ul>
</div>
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com2tag:blogger.com,1999:blog-7623640872736089068.post-67646107480518671392015-06-22T16:36:00.000+03:002015-07-07T23:23:09.022+03:00SHA1 compile time checked literals: F# vs Nemerle vs D<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
I've always been interested in metaprogramming. Sooner or later, I'm starting to feel constrained within a language without it. F# is a really nice language, but I'm afraid I'd have got bored with it if it'd not have Type Providers, for example. Why metaprogramming is so important? Because it allows changing a language without cracking the compiler. It allows making things which seemed to be impossible to implement.<br />
<br />
I'm dealing with cryptography hashes a lot at work, nothing rocket since, just MD5, SHA-1 and so on. And I write tons of tests where such hashes are used in form of string literals, like this:<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/14c241fecf6dc64bf11c.js"></script>
<br />
The problem with this code is that the compiler cannot guarantee that the hex string in the last line represents a valid SHA-1. If it does not, the test will fail at runtime for a reason it's not intended to.<br />
<br />
OK, now we can formulate our task: provide a language construct to enforce a string literal being a valid SHA-1 hexadecimal, at compile time. We will explore how much work it's required to implement such a simple feature in F#, Nemerle and D. It's also interesting how well the development workflow is for each of this languages - IDE integration, error reporting and testing cycle.<br />
<br />
<h2 style="text-align: left;">
F#</h2>
<div>
<br /></div>
Using Type Providers is the only way to check (at compile time) that a string is a valid hex one and that it's length is exactly 40 characters (SHA-1 is a 20-bytes hash). Actually, I've written <a href="https://github.com/vasily-kirichenko/FSharp.Data.HexProvider">this type provider</a> before. The interesting part looks like this:<br />
<br />
<br /></div>
<script src="https://gist.github.com/vasily-kirichenko/2cf54dc35b3b5a1f5e42.js"></script>
It includes caching, and `HexParser` module is not shown, but those details are not important here. It's simple and it generates Value property which directly returns byte array, created in compile-time.<br />
<br />
Error reporting:
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-t5HSkuJVgAM/VYgL_R0wQ0I/AAAAAAAALHA/W5Lbh2DuzQ0/s1600/sha1_fsharp_tp_error1.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: left;"><img border="0" src="http://4.bp.blogspot.com/-t5HSkuJVgAM/VYgL_R0wQ0I/AAAAAAAALHA/W5Lbh2DuzQ0/s1600/sha1_fsharp_tp_error1.png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-h3JsOsfDCwE/VYgL_QOSOFI/AAAAAAAALG8/xQ5XlA1yQZA/s1600/sha1_fsharp_tp_error2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: left;"><img border="0" src="http://4.bp.blogspot.com/-h3JsOsfDCwE/VYgL_QOSOFI/AAAAAAAALG8/xQ5XlA1yQZA/s1600/sha1_fsharp_tp_error2.png" /></a></div>
<br />
<br />
<br />
<br />
<h2>
Nemerle</h2>
Nemerle has full fledged macros, which strictly more powerful than F#'s Type Providers. Let's see if they allow solving the task in an elegant way:<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/17ce05ac4d63cbb33635.js"></script>
</div>
<br />
Error reporting:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-IgSy0gno0V8/VYgNSBurIvI/AAAAAAAALHg/o6d_ycG4_Qo/s1600/sha1_nemerle_macros_error1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-IgSy0gno0V8/VYgNSBurIvI/AAAAAAAALHg/o6d_ycG4_Qo/s1600/sha1_nemerle_macros_error1.png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-feDi0ge2BsE/VYgNSJzLw9I/AAAAAAAALHc/a8wOdDNfl2I/s1600/sha1_nemerle_macros_error2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-feDi0ge2BsE/VYgNSJzLw9I/AAAAAAAALHc/a8wOdDNfl2I/s1600/sha1_nemerle_macros_error2.png" /></a></div>
<br />
<h2>
D</h2>
<br />
<script src="https://gist.github.com/vasily-kirichenko/224e85200fa79155c66c.js"></script>
The code does not use any unusual stuff and does not manipulate AST. Just plane D code. Very elegant. Note that the template is defined in the same file as its usage. Contrast this with F# and Nemerle where you have to place your Type Provider / macros into a dedicated assembly.
<br />
<br />
Error reporting:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-XIG1YRwzZW8/VYgOePPSKbI/AAAAAAAALHw/nTYNWa2LjXU/s1600/sha1_d_template_error1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-XIG1YRwzZW8/VYgOePPSKbI/AAAAAAAALHw/nTYNWa2LjXU/s1600/sha1_d_template_error1.png" /></a></div>
<br />
The error is located in the template itself, not at the instantiation point though.<br />
<br />
<h2>
Performance</h2>
I added 1000 usages of the TP, macro and template and measured compilation time.<br />
<br />
<ul style="text-align: left;">
<li>F# - 5 seconds</li>
<li>Nemerle - 2 seconds</li>
<li>D - the compiler crashes with "Error: out of memory" after 1 minute work.</li>
</ul>
</div>
</div>
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com2tag:blogger.com,1999:blog-7623640872736089068.post-43783214769236485272015-06-20T17:20:00.000+03:002015-06-21T14:24:50.617+03:00Fib: C++, C# and GDC<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
As a reference implementation, I added C++ one:<br />
<br />
<br /></div>
<script src="https://gist.github.com/vasily-kirichenko/31ff76ff87e071491071.js"></script>
It's execution time is 1.33 seconds, which surprisingly is not the best result so far.
<br />
<div>
A C# version:
<br />
<br /></div>
<script src="https://gist.github.com/vasily-kirichenko/d24c537d3d63cbd94410.js"></script>
Also, I compiled <a href="http://vaskir.blogspot.ru/2014/10/d.html">this D code</a> with GDC compiler and it executed in 990 ms, which is the best result:<br />
<br />
<ul style="background-color: white; color: #666666; font-family: Georgia, Utopia, 'Palatino Linotype', Palatino, serif; font-size: 16.5px; line-height: 23.1000003814697px; margin: 0.5em 0px; padding: 0px 2.5em;">
<li style="margin: 0px 0px 0.25em; padding: 0px;">D (GDC) - 0.990</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">C# - 1.26</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 23.1000003814697px;">D (DMD) - 1.3</span></li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 23.1000003814697px;">C++ - 1.33</span></li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 23.1000003814697px;">F# - 1.38</span></li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Nemerle - 1.45</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 23.1000003814697px;">Rust - 1.66</span></li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Go - 2.38</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Haskell - 2.8</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 23.1000003814697px;">Clojure - 9</span></li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Erlang - 17</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Ruby - 60</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Python - 120</li>
</ul>
<div>
<br /></div>
<div>
Unfortunately, I have not managed to compile the D code with LDC compiler, it returns the following error:</div>
<div>
<br /></div>
<div>
<div>
Building: DFib (Release)</div>
<div>
Performing main compilation...</div>
<div>
Current dictionary: d:\git\DFib\DFib</div>
<div>
D:\ldc2-0.15.2-beta1-win64-msvc\bin\ldc2.exe -O3 -release "main.d" "-od=obj\Release" "-of=d:\git\DFib\DFib\bin\Release\DFib.exe"</div>
<div>
LINK : fatal error LNK1181: cannot open input file 'kernel32.lib'</div>
<div>
Error: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\link.exe failed with status: 1181</div>
<div>
Exit code 1181</div>
</div>
</div>
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com0tag:blogger.com,1999:blog-7623640872736089068.post-28051534454553316952015-05-16T21:20:00.000+03:002015-05-16T21:20:30.452+03:00Composing custom error types in F#<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: left;">
I strongly believe that we should keep code as referential transparent as possible. Unfortunately, F# language does not encourage programmers to use Either monad to deal with errors. The common practice in the community is using common in the rest .NET (imperative) world exception based approach. From my experienced, almost all bugs found in production are caused by unhandled exceptions. </div>
<div style="text-align: left;">
<br /></div>
<h3 style="text-align: left;">
The problem</h3>
<div>
<br /></div>
<div>
In our project we've used the Either monad for error handling with great success for about two years. <a href="https://github.com/jack-pappas/ExtCore" target="_blank">ExtCore</a> is a great library making dealing with Either, Reader, State and other monads and their combinations really easy. Consider a typical error handling code, which make use Choice computation expression from ExtCore:</div>
<div>
<br /></div>
<div>
<script src="https://gist.github.com/vasily-kirichenko/e5929f7e03f01ae9cec0.js"></script>
</div>
<div>
<br /></div>
<div>
The code is a bit hairy because of explicit error mapping. We could introduce an operator as a synonym for Choice.mapError, like <!>, after which the code could become a bit cleaner:<br />
<br /></div>
<script src="https://gist.github.com/vasily-kirichenko/b20bc2c9659df8855f25.js"></script>
<br />
<div>
(actually it's the approach we use at in our team).</div>
<br />
<br />
<h3 style="text-align: left;">
Rust composable errors</h3>
<div>
<br /></div>
<div>
I was completely happy until today, when I read <a href="http://blog.burntsushi.net/rust-error-handling/#composing-custom-error-types" target="_blank">Error Handling in Rust</a> article and found out how elegantly errors are composed using From trait. By implementing it for an error type, you enable auto converting lower level errors to be convertable to it by try! macro, which eliminates error mapping completely. I encourage the reader to read that article because it explains good error handling in general, it's totally applicable to F#.<br />
<br /></div>
<h3 style="text-align: left;">
Porting to F#</h3>
<div>
<br /></div>
<div style="text-align: left;">
Unfortunately, there's no static interface implementation neither in F# nor in .NET, so we cannot just introduce IError with a static member From: 'a -> 'this, like we can in Rust. But in F# we can use statically resolved type parameters to get the result we need. The idea is that each "higher level" error type defines a bunch of static methods, each of which converts some lower level error type to one of the error type cases: </div>
<div style="text-align: left;">
<br /></div>
<script src="https://gist.github.com/vasily-kirichenko/d3859ab1e7793766c3bf.js"></script>
Now we can write a generic function which can create any higher level error type, which defines From methods:<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/ef6a42b01071661654ec.js"></script>
Now we can rewrite our processFile function without explicit mapping to concrete error cases:<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/5bac62d10e038b97919a.js"></script>
Great. But it's still not as clean. The remaining bit is to modify Choice computation expression builder so that it can do the same implicit conversion in its Bind method (its ChoiceBuilder from ExtCore as is, but without For and While methods):<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/cd8a04cd647803374f5a.js"></script>
The CE now requires all errors to be convertable to its main error type, including the error type itself, so we have to add one more From static method to Error type, and we finally can remove any noise from our processFile function:<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/84e898e04040d1019ed8.js"></script>
</div>
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com2tag:blogger.com,1999:blog-7623640872736089068.post-79823543356277647902015-05-04T22:38:00.000+03:002015-06-21T14:24:01.426+03:00Go: fib<div dir="ltr" style="text-align: left;" trbidi="on">
Go code is relatively low-level since it does not have "foreach over range" syntax construct:<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/82091b764d3ccf28faf2.js"></script>
Results are not as impressive for a systems language: 2.38 seconds. And it lays below Rust but under Haskell:
<br />
<ul style="background-color: white; color: #666666; font-family: Georgia, Utopia, 'Palatino Linotype', Palatino, serif; font-size: 16.5px; line-height: 23.1000003814697px; margin: 0.5em 0px; padding: 0px 2.5em;">
<li>C# - 1.26</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 23.1000003814697px;">D (DMD) - 1.3</span></li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 23.1000003814697px;">F# - 1.38</span></li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 23.1000003814697px;">Nemerle - 1.45</span></li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 23.1000003814697px;">Rust - 1.66</span></li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Go - 2.38</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Haskell - 2.8</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 23.1000003814697px;">Clojure - 9</span></li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Erlang - 17</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Ruby - 60</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Python - 120</li>
</ul>
</div>
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com3tag:blogger.com,1999:blog-7623640872736089068.post-31618719464642136872015-04-11T17:40:00.001+03:002015-07-20T22:10:32.787+03:00Computing cryptography hashes: Rust, F#, D and Scala<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
Let's compare how fast Rust, D and F# (.NET actually) at computing cryptography hashes, namely MD5, SHA1, SHA256 and SHA512. We're going to use <a href="https://crates.io/crates/rust-crypto" target="_blank">rust-crypto cargo</a>:<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/84d5ef2a09ddaaa9eb38.js"></script>
Results:<br />
<ul style="text-align: left;">
<li>MD5 - 3.39s </li>
<li>SHA1 - 2.89s </li>
<li>SHA256 - 6.97s</li>
<li>SHA512 - 4.47s</li>
</ul>
<div>
<br />
Now the F# code:</div>
<br />
<div>
<script src="https://gist.github.com/vasily-kirichenko/b376de7968f80c0faab6.js"></script>
<br />
<div>
Results (.NET 4.5, VS 2013, F# 3.1):<br />
<ul style="text-align: left;">
<li>MD5CryptoServiceProvider - 2.32s (32% faster)</li>
<li>SHA1CryptoServiceProvider - 2.92s (1% slower)</li>
<li>SHA256Managed - 16.50s (236% slower)</li>
<li>SHA256CryptoServiceProvider - 11.50s (164% slower)</li>
<li>SHA256Cng - 11.71s (168% slower)</li>
<li>SHA512Managed - 61.04s (1365% slower)</li>
<li>SHA512CryptoServiceProvider - 21.88s (489% slower)</li>
<li>SHA512Cng - 22.19s (496% slower)</li>
</ul>
<div>
(.NET 4.6, VS 2015, F# 4.0):<br />
<br />
<ul style="text-align: left;">
<li>MD5CryptoServiceProvider elapled 2.55</li>
<li>SHA1CryptoServiceProvider elapled 2.89</li>
<li>SHA256Managed elapled 17.01</li>
<li>SHA256CryptoServiceProvider elapled 8.74</li>
<li>SHA256Cng elapled 8.75</li>
<li>SHA512Managed elapled 23.42</li>
<li>SHA512CryptoServiceProvider 5.81</li>
<li>SHA512Cng elapled 5.79</li>
</ul>
<br />
<br />
<br />
D:</div>
<div>
<br /></div>
<script src="https://gist.github.com/vasily-kirichenko/f2971d6b457e2d0dfc32.js"></script>
<br />
<div>
<br /></div>
DMD
<br />
<div>
<ul>
<li>MD5 - 16.05s (470% slower)</li>
<li>SHA1 - 2.35s (19% faster)</li>
<li>SHA256 - 47.96s (690% slower (!))</li>
<li>SHA512 - 61.47s (1375% slower (!))</li>
</ul>
</div>
LDC2
<br />
<div>
<ul>
<li>MD5 - 2,18s (55% faster)</li>
<li>SHA1 - 2.88s (same)</li>
<li>SHA256 - 6,79s (3% faster)</li>
<li>SHA512 - 4,6s (3% slower)</li>
</ul>
</div>
<div>
GDC<br />
<ul style="text-align: left;">
<li>MD5 - 2,43 (29% faster)</li>
<li>SHA1 - 2,84 (2% faster)</li>
<li>SHA256 - 12,62 (45% slower)</li>
<li>SHA512 - 8,56 (48% slower)</li>
</ul>
<br />
<br />
Scala:<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/2192a144e2a8e7411271.js"></script>
<br />
<div>
<br /></div>
<div>
<ul>
<li>MD5 - 4.2s (23% slower)</li>
<li>SHA1 - 6.09s (110% slower)</li>
<li>SHA256 - 9.96s (42% slower)</li>
<li>SHA512 - 7.32s (63% slower)</li>
</ul>
</div>
Interesting things:<br />
<br />
<ul style="text-align: left;">
<li>Rust and D (LDC2) show very close results. D is significantly faster on MD5, so it's the winner!</li>
<li>D (DMD) has very bad performance on all algorithms, except SHA1, where it's won.</li>
<li>SHA512Managed .NET class is very slow. Do not use it.</li>
</ul>
<div>
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-h5YzB_67-oU/Va1HlsSai1I/AAAAAAAALIQ/oCmmT9xJgFM/s1600/%25D0%25A1%25D0%25BD%25D0%25B8%25D0%25BC%25D0%25BE%25D0%25BA.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-h5YzB_67-oU/Va1HlsSai1I/AAAAAAAALIQ/oCmmT9xJgFM/s1600/%25D0%25A1%25D0%25BD%25D0%25B8%25D0%25BC%25D0%25BE%25D0%25BA.PNG" /></a></div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br /></div>
</div>
</div>
</div>
</div>
</div>
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com15tag:blogger.com,1999:blog-7623640872736089068.post-29182211682376711302015-03-29T21:05:00.000+03:002015-06-21T14:23:18.750+03:00Rust: fib<div dir="ltr" style="text-align: left;" trbidi="on">
Rust is an interesting language. It is not a primitive one, like Go where we don't have ADTs, pattern matching and generics (but we do have Nils). And it's advertising as a safe and performant system language. Today is the very first day I'm looking at it. Let's "smoke" test it with Fibonacci :)<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/0b3d2b6a72ba2490d3fc.js"></script>
<br />
Debug: 3.44 seconds, release: 1.66 seconds. This is not very impressive, but pretty fast indeed.<br />
<ul>
<li>C# - 1.26</li>
<li>D (DMD) - 1.3</li>
<li>F# - 1.38</li>
<li>Nemerle - 1.45</li>
<li>Rust - 1.66</li>
<li>Haskell - 2.8</li>
<li>Clojure - 9</li>
<li>Erlang - 17</li>
<li>Ruby - 60</li>
<li>Python - 120</li>
</ul>
<div>
It's very interesting how it'll behave in concurrent Fibonacci test.<br />
<br />
The compiler is quite slow: it takes 2-3 seconds to build this tiny program.<br />
<br /></div>
</div>
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com0tag:blogger.com,1999:blog-7623640872736089068.post-28500256269988481462015-01-10T17:11:00.000+03:002015-04-18T21:07:49.402+03:00Parallel reduce: Hopac, Asyncs, Tasks and Scala's Futures<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
</div>
Tuomas Hietanen <a href="http://fssnip.net/pa">posted a parallel reduce function</a> that uses TPL Tasks. I found it interesting to compare performance of this function with analogues implemented using F# Asyncs, Hopac Jobs and Scala Futures.</div>
The author uses noop long-running reduce function to show that it's really run in parallel. In this blog post we are benchmarking another aspect of the implementations: how much extra cost is introduced by a particular parallezation mechanism (library) itself.
<br />
<br />
We translate the original code almost as is to Tasks and Hopac:
<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/ecaedab2b58e1b88e0b4.js"></script></div>
<br />
And Scala's Futures:
<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/6e2f87cc9b4f34e501bf.js"></script>
<br />
The results (Core i5, 4 cores):<br />
<br />
<ul style="text-align: left;">
<li>Sequential List.reduce: Real: 00:00:00.014, CPU: 00:00:00.015, GC gen0: 0, gen1: 0, gen2: 0 </li>
<li>Tasks: Real: 00:00:01.790, CPU: 00:00:05.678, GC gen0: 36, gen1: 10, gen2: 1 </li>
<li>Hopac: Real: 00:00:00.514, CPU: 00:00:01.482, GC gen0: 27, gen1: 2, gen2: 1 </li>
<li>Asyncs: Real: 00:00:37.872, CPU: 00:01:48.405, GC gen0: 90, gen1: 29, gen2: 4</li>
<li>Scala Futures: 4.8 seconds</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-9rbdH1zZ9zo/VTKbgE8NjTI/AAAAAAAAJ8c/QR332NVzkUQ/s1600/%D0%91%D0%B5%D0%B7%D1%8B%D0%BC%D1%8F%D0%BD%D0%BD%D1%8B%D0%B9.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-9rbdH1zZ9zo/VTKbgE8NjTI/AAAAAAAAJ8c/QR332NVzkUQ/s1600/%D0%91%D0%B5%D0%B7%D1%8B%D0%BC%D1%8F%D0%BD%D0%BD%D1%8B%D0%B9.png" /></a></div>
<br />
<div style="text-align: center;">
(Hopac - 3.4 times faster, Asyncs - 21.1 times slower, Scala - 1.8 times slower)</div>
<br /></div>
<div>
Hopac is ~3.5 times faster than TPL. What's wrong with Asyncs? I don't know. Maybe they are not intended for highly concurrent scenarios. Or my code may not be the most efficient. Any ideas, guys?</div>
<div>
<br /></div>
<div>
Let's test the leaders on larger arrays:<br />
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-dUecaV7nE7Y/VTKbySH_7II/AAAAAAAAJ8k/zURHhkKAnV8/s1600/%D0%91%D0%B5%D0%B7%D1%8B%D0%BC%D1%8F%D0%BD%D0%BD%D1%8B%D0%B9.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-dUecaV7nE7Y/VTKbySH_7II/AAAAAAAAJ8k/zURHhkKAnV8/s1600/%D0%91%D0%B5%D0%B7%D1%8B%D0%BC%D1%8F%D0%BD%D0%BD%D1%8B%D0%B9.png" /></a></div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
(Hopac is 3.37 times faster, Scala is 1.5 times slower)</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-hYtG_P-j7Qk/VTKb8wGWnAI/AAAAAAAAJ8s/GjtNd0uRVo4/s1600/%D0%91%D0%B5%D0%B7%D1%8B%D0%BC%D1%8F%D0%BD%D0%BD%D1%8B%D0%B9.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-hYtG_P-j7Qk/VTKb8wGWnAI/AAAAAAAAJ8s/GjtNd0uRVo4/s1600/%D0%91%D0%B5%D0%B7%D1%8B%D0%BC%D1%8F%D0%BD%D0%BD%D1%8B%D0%B9.png" /></a></div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
(Hopac is 5.25 times faster, Scala is 1.05 times slower)</div>
<div>
<br /></div>
</div>
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com5tag:blogger.com,1999:blog-7623640872736089068.post-75566879804710220302015-01-07T20:51:00.002+03:002017-05-10T17:31:57.788+03:00Fibonacci: Hopac vs Async vs TPL Tasks on .NET and Mono<div dir="ltr" style="text-align: left;" trbidi="on">
Hopac claims that its Jobs are much more lightweight that F# Asyncs. There are many benchmarks on Hopac github repository, but I wanted to make a simple and straightforward benchmark and what could be simpler that parallel Fibonacci algorithm? :) (actually there's a more comprehensive benchmark in the Hopac repository itself, see <a href="https://github.com/Hopac/Hopac/blob/master/Benchmarks/Fibonacci/Fibonacci.fs" target="_blank">Fibonacci.fs</a>)<br />
<br />
Sequential Fibonacci function is usually defined as<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/b78c68ec8c7ba10fa0da.js"></script>
So write a parallel version in Hopac where each step is performed in a Job and all these Jobs are (potentially) run in Parallel by Hopac's scheduler<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/b9e225daa770c5f0eb53.js"></script>
An equivalent parallel algorithm written using F# Asyncs<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/3213a23264d101552895.js"></script>
...and using TPL Tasks<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/de2c73438a06aa3baca2.js"></script>
All three functions create *a lot* of parallel jobs/asyncs/tasks. For example, for calculating fib (34) they create ~14 million of jobs (this is why Fibonacci was chose for this test). To make them work efficiently we will use the sequential version of fib for small N, then switch to parallel version<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/0b58841add2b5cb9875a.js"></script>
Now we can run both of the function with different "level"s in order to find on which value the functions starts to perform good (x-axis: level, y-axis: time (ms), blue line: the sequential function, orange line: hopac/async/tasks function):<br />
<br />
Hopac<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-1XlpqnPxuzA/VK2NrL4N1PI/AAAAAAAAJ18/HrbKXfGs0ms/s1600/hopac_42.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="270" src="https://2.bp.blogspot.com/-1XlpqnPxuzA/VK2NrL4N1PI/AAAAAAAAJ18/HrbKXfGs0ms/s1600/hopac_42.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
Async</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-p8ScFs71GdE/VK2NyAHKchI/AAAAAAAAJ2E/0wi1TxRhrSo/s1600/async_42.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="270" src="https://2.bp.blogspot.com/-p8ScFs71GdE/VK2NyAHKchI/AAAAAAAAJ2E/0wi1TxRhrSo/s1600/async_42.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
Tasks</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-ESa5b-QajWo/VK42VW-KuwI/AAAAAAAAJ2o/PC9qpylcQOw/s1600/task_42.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="270" src="https://1.bp.blogspot.com/-ESa5b-QajWo/VK42VW-KuwI/AAAAAAAAJ2o/PC9qpylcQOw/s1600/task_42.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: left;">
Hopac reaches performance equivalent to the sequential implementation at level = 9, Async - at level = 17 and Tasks at level = 11.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
If we modify the code so we can count how many jobs/asyncs are created during the calculation</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<script src="https://gist.github.com/vasily-kirichenko/f614bf603a550e73ad38.js"></script></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
We get the following results (n = 42): </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
* Sequential, Real: 00:00:01.849, CPU: 00:00:01.840, GC gen0: 0, gen1: 0, gen2: 0</div>
<div class="separator" style="clear: both; text-align: left;">
* Hopac (level = 9) jobs: 28761996, Real: 00:00:01.700, CPU: 00:00:05.600, GC gen0: 89, gen1: 1, gen2: 0</div>
<div class="separator" style="clear: both; text-align: left;">
* Async (level = 17) asyncs: 605898, Real: 00:00:01.515, CPU: 00:00:04.804, GC gen0: 4, gen1: 2, gen2: 0</div>
<div class="separator" style="clear: both; text-align: left;">
* Tasks (level = 11) tasks: 5675789, Real: 00:00:01.813, CPU: 00:00:06.302, GC gen0: 18, gen1: 0, gen2: 0</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
So, Hopac was able to create and processed ~47x more jobs than Async and ~5x more jobs than Tasks. Hopac is impressive and F# Asyncs are frustrating. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
PS: Rewriting the async version without async computation explicit expression, like this</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<script src="https://gist.github.com/vasily-kirichenko/bbc757fdb320ac10a8f3.js"></script></div>
<div class="separator" style="clear: both; text-align: left;">
does not improve performance at all. </div>
<br />
<span style="font-size: large;"><b>Running on Mono (Ubuntu 14.10 x64, mono 3.10)</b></span><br />
<br />
<div class="separator" style="clear: both; text-align: left;">
* Sequential, <span style="background-color: white; color: #222222; font-family: "arial" , sans-serif;">Real: 00:00:02.637, CPU: 00:00:02.636, GC gen0: 0, gen1: 0</span></div>
<div class="separator" style="clear: both; text-align: left;">
* Hopac (level = 17) jobs: <span style="background-color: white; color: #222222; font-family: "arial" , sans-serif;">629133</span>, <span style="background-color: white; color: #222222; font-family: "arial" , sans-serif;">Real: 00:00:02.447, CPU: 00:00:06.106, GC gen0: 26, gen1: 1</span></div>
<div class="separator" style="clear: both; text-align: left;">
* Async (level = 21) asyncs: <span style="background-color: white; color: #222222; font-family: "arial" , sans-serif;">92375</span>, <span style="background-color: white; color: #222222; font-family: "arial" , sans-serif;">Real: 00:00:02.845, CPU: 00:00:05.590, GC gen0: 86, gen1: 3</span></div>
<div class="separator" style="clear: both; text-align: left;">
* Tasks (level = 33) tasks: <span style="background-color: white; color: #222222; font-family: "arial" , sans-serif;">143</span>, <span style="background-color: white; color: #222222; font-family: "arial" , sans-serif;">Real: 00:00:14.111, CPU: 00:00:03.782, GC gen0: 0, gen1: 0</span></div>
<br />
Hopac can handle ~6.8x more jobs than F# Async. I'm not sure if F# asyncs performs very well on Mono or it's because everything works extremely slowly there. What about TPL, it's obviously broken on Mono (official Hopac Fibonacci benchmark does not even run TPL version on mono: <a href="https://github.com/Hopac/Hopac/blob/master/Benchmarks/Fibonacci/Fibonacci.fs#L233" target="_blank">Fibonacci.fs#L233</a>).<br />
<br />
<h2 style="text-align: left;">
Update 10.09.2017 - use BenchmarkDotNet</h2>
<div>
<br /></div>
<div>
<div>
n = 30, level = 15<br />
<br /></div>
<div>
<pre> Method | Mean | Error | StdDev |
------- |---------:|----------:|----------:|
Fib | 8.208 ms | 0.0432 ms | 0.0383 ms |
HFib | 1.860 ms | 0.0045 ms | 0.0042 ms |
AFib | 4.921 ms | 0.0330 ms | 0.0292 ms |
TFib | 2.229 ms | 0.0184 ms | 0.0172 ms |
</pre>
</div>
<div>
<br /></div>
<div>
n = 20, level = 0<br />
<br /></div>
<pre> Method | Mean | Error | StdDev |
------- |-------------:|-----------:|-------------:|
Fib | 68.21 us | 1.258 us | 1.177 us |
HFib | 356.21 us | 7.180 us | 11.595 us |
AFib | 31,815.44 us | 636.249 us | 1,524.413 us |
TFib | 1,623.25 us | 32.206 us | 33.073 us |
</pre>
</div>
</div>
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com1tag:blogger.com,1999:blog-7623640872736089068.post-13163677243051461952014-10-25T17:44:00.002+04:002015-06-21T14:22:24.953+03:00D<div dir="ltr" style="text-align: left;" trbidi="on">
I've to say, D is very interesting language with several unique features. What about performance? How it compares to VM-based languages?<br />
<br />
<script src="https://gist.github.com/vasily-kirichenko/9d859b8f78fc85d276db.js"></script><br />
<br />
It took 3.6 seconds in debug mode and 1.3 seconds in release mode, which is on pair with F#.<br />
<br />
<br />
<ul>
<li>C# - 1.26</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 18.4799995422363px;">D (DMD) - 1.3</span></li>
<li>F# - 1.38</li>
<li>Nemerle - 1.45</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;"><span style="line-height: 18.4799995422363px;">Haskell - 2.8</span></li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Clojure - 9</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Erlang - 17</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Ruby - 60</li>
<li style="margin: 0px 0px 0.25em; padding: 0px;">Python - 120</li>
</ul>
</div>
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com0tag:blogger.com,1999:blog-7623640872736089068.post-86086483197821956822014-08-15T16:15:00.002+04:002015-06-08T21:04:31.109+03:00Scala pros and cons from F# dev view<div dir="ltr" style="text-align: left;" trbidi="on">
Recently I started to learn Scala (for about 2 weeks now). Here is prons and cons so far (note: I've not written any serious code yet, just have read "Scala for the impatient" and now reading "Programming in Scala" by Odersky):
<br />
<br />
<h3>
Prons</h3>
<div>
<ul style="text-align: left;">
<li>Passing not evaluated block as argument ("by-name arguments". Allows to develop better DSLs)</li>
<li>Macros!</li>
<li>There are few libraries written with macros, impossible to implement in a language like c# or f# (MacWire etc.)</li>
</ul>
</div>
<h3>
Cons</h3>
<div>
<ul style="text-align: left;">
<li>No not-nullable types (this is a huge one)</li>
<li>Not whitespace sensitive (curly braces everywhere) </li>
<li>No type inference for arguments and, sometimes, for result type (signatures involving generic types may be really hairy) </li>
<li>No compiler warning on implicitly discarded expression value (possibly wrong code like arr.map(x => x * 2); arr.map(x => x * 3). The result of the first map is discarded silently. In contrast, F# forces us to write arr |> Array.map (fun x -> x * 2) |> ignore; arr |> Array.map (fun x -> x * 3).</li>
</ul>
</div>
</div>
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com1tag:blogger.com,1999:blog-7623640872736089068.post-80181946719306543752014-08-13T22:19:00.002+04:002014-08-13T22:21:21.487+04:00STM revisited: add ScalaSome time ago I <a href="http://vaskir.blogspot.ru/2013/09/stm-f-vs-haskell.html">compared</a> F# and Haskell STM implementation performance. Today I'm adding Scala into it:
<p>
<script src="https://gist.github.com/vasily-kirichenko/f6d9d7ecf04ab0fca5ef.js"></script>
<p>
So, it's more than two times slower than Haskell, but more than 3 times faster than F#. Interesting.
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com0tag:blogger.com,1999:blog-7623640872736089068.post-73189842601393673572014-08-10T11:57:00.001+04:002014-08-10T11:57:45.640+04:00Duck typing in ScalaScala keeps surprising me. It has much good stuff that F# has. For example, I believed that statically resolved type parameters are unique to F#. Turns out this is not the case. Scala has equivalent feature called "structural types". It has nice syntax compared to F#'s statically resolved type parameters. However, it uses reflection under the hood while F# uses inlining to instantiate functions in-place at compile time. This approach should definitely have awful performance characteristics. Surprisingly, it's not the case:
<p>
<script src="https://gist.github.com/vasily-kirichenko/73647036df457338c6f6.js"></script>
<p>
Static call took about 0.5 seconds, "duck typing" call took about 4 seconds. It only 8-10 times slower than static call. Frankly, I expected something like 100x - 1000x degradation. So, it's not as fast as the equivalent feature in F#, but it certainly practically useful in many circumstances.
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com0tag:blogger.com,1999:blog-7623640872736089068.post-92011084866922691082013-09-22T20:57:00.000+04:002013-09-22T20:57:28.778+04:00STM: F# vs HaskellSTM is a very nice parallel programming model used intensively in Haskell and Clojure. There's <a href="https://github.com/fsharp/fsharpx/blob/master/src/FSharpx.Core/Stm.fs">a F# implementation</a> which can be found in <a href="http://www.nuget.org/packages/FSharpx.Core/">FSharpx</a> library.
<p>Today I'm going to test performance of both the Haskell and the F# STMs. The test is very simple - read a couple TVars, check their equality, then write them back incremented by 1, repeat a million times.
<p>First, the Haskell code:
<script src="https://gist.github.com/vasily-kirichenko/6661713.js"></script>
<p>So, it took about 170 ms. OK, now F#:
<script src="https://gist.github.com/vasily-kirichenko/6661832.js"></script>
It took about 1,6 seconds which is an order of magnitude slower than the Haskell result. It's rather frustrating. Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com3tag:blogger.com,1999:blog-7623640872736089068.post-52602878702961296172013-09-01T18:38:00.001+04:002013-09-01T18:38:59.244+04:00Grouping consecutive integers in F# and HaskellLet's look at what F# and Haskell can offer us while reimplementing <a href="http://bugsquash.blogspot.ru/2010/01/grouping-consecutive-integers-in-c.html">grouping consecutive integers in C#</a> algorithm.
<p>F#:
<script src="https://gist.github.com/vasily-kirichenko/6404801.js"></script>
<p>Haskell:
<script src="https://gist.github.com/vasily-kirichenko/6404809.js"></script>
<p>
For my current taste, the Haskell version is more readable due to the awesome separate type annotation and to the lovely Erlang-style pattern matching on function arguments.Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com0tag:blogger.com,1999:blog-7623640872736089068.post-5783457893136606972013-08-24T18:44:00.001+04:002015-06-21T14:21:28.900+03:00Haskell: performance<div dir="ltr" style="text-align: left;" trbidi="on">
It turned out that it's not Haskell who was slow in my previous Fibonacci test. It was my lack of Haskell knowledge. Haskell has two integral types - Int, which has bounds -2147483648..2147483647 and Integer, which is unbounded. Both types implement Integral type class, so out fib function can be defined in terms of this type class:
<br />
<script src="https://gist.github.com/vasily-kirichenko/6328453.js"></script>
OK, now we can test performance of the function parametrizing it with the two concrete types. Integer first:
<br />
<script src="https://gist.github.com/vasily-kirichenko/6328492.js"></script>
We get our previous result ~15 seconds which is rather slow.
Now test it with Int type:
<br />
<script src="https://gist.github.com/vasily-kirichenko/6328516.js"></script>
Whoa! The Int type is ~6 times faster than Integer!
And with result of 2.8 seconds Haskell's took the third position in our small rating :) Current list (in seconds):
<br />
<ul>
<li>C# - 1.26</li>
<li>F# - 1.38</li>
<li>Nemerle - 1.45</li>
<li>Haskell - 2.8</li>
<li>Clojure - 9</li>
<li>Erlang - 17
</li>
<li>Ruby - 60
</li>
<li>Python - 120
</li>
</ul>
<br />
<br />
<br />
<br />
<br /></div>
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com1tag:blogger.com,1999:blog-7623640872736089068.post-87723056944236908472013-08-17T22:05:00.002+04:002013-08-17T22:05:10.291+04:00Beginning HaskellOkey, it passed about a year I started learn and use F# and it's now time to learn Haskell.
As usual, I started from the naive Fibonacci function:
<script src="https://gist.github.com/vasily-kirichenko/6258008.js"></script>
The performance in this particular algorithm is not fantastic, it's actually ~4 times slower than F#. It's OK for now.Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com0tag:blogger.com,1999:blog-7623640872736089068.post-11599135317523758612013-06-16T12:52:00.000+04:002013-06-16T12:52:39.172+04:00The Either monad: we can finally get rid of exceptions<a href="https://twitter.com/jessitron">Jessica Kerr</a> <a href="http://blog.jessitron.com/2013/06/whats-dirtier-than-comments-exceptions.html">recently wrote</a> on the very interesting topic: what the best way to get rid of exceptions and of the mess they introduce into the program flow.<br />
Simply put, she's gently introduced the Either monad in Scala language.<br />
Although I find Scala to be a very advanced OO language with reasonably good FP support, I don't think the code Jessica used in her post can force anybody to change the habitual exception handling flow in favor of the Data Flow. This's why: Scala is too verbose.<br />
But this is not the case in a more advanced functional language like OCaml, Haskell or F#. Let's take a look what the latter can offer:<p>
<script src="https://gist.github.com/vasily-kirichenko/5791396.js"></script>
<p>
The code is much more clear because of using the monadic function composition (>=>) and the amazing type inference. <br>
Conclusion: if you do use monands, use their full power.
Vasilyhttp://www.blogger.com/profile/08538100460991899296noreply@blogger.com0