<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<div class="markdown-here-wrapper" data-md-url="Thunderbird"
style="font-family: Ubuntu,Cantarell,Deja Vu Sans,sans-serif;
font-size: 10pt;">
<p style="margin: 0px 0px 1.2em ! important;">On 2017-12-07 12:49
AM, Jonas Scholl wrote:</p>
<blockquote style="margin: 1.2em 0px;border-left: 4px solid
rgb(221, 221, 221); padding: 0px 1em; color: rgb(119, 119, 119);
quotes: none;">
<p style="margin: 0px 0px 1.2em ! important;">Looking at the
produced core of both versions reveals that in the profiled
build a closure of type Regex is floated to top level. The
non-profiled build doesn’t do this, thus it recompiles the
regex for every iteration. This is most likely the source of
the slowdown of the non-profiled build.</p>
</blockquote>
<p style="margin: 0px 0px 1.2em ! important;">Thanks, Jonas. This
does indeed seem to be the problem. I changed the code to use a
compiled regex (with <code style="font-size: 0.95em; font-family: Consolas,Inconsolata,Deja Vu Sans Mono,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">makeRegex</code>
and <code style="font-size: 0.95em; font-family: Consolas,Inconsolata,Deja Vu Sans Mono,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">match</code>
instead of <code style="font-size: 0.95em; font-family: Consolas,Inconsolata,Deja Vu Sans Mono,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">=~</code>)
but in the non-profiling case the run-time doesn’t improve
unless I float the compiled regex myself:</p>
<pre style="font-size: 0.95em; font-family: Consolas,Inconsolata,Deja Vu Sans Mono,Courier,monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code class="hljs language-Haskell" style="font-size: 0.95em; font-family: Consolas,Inconsolata,Deja Vu Sans Mono,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block ! important;display: block; overflow-x: auto; padding: 0.5em; color: rgb(51, 51, 51); background: rgb(248, 248, 248) none repeat scroll 0% 0%; -moz-text-size-adjust: none;"><span class="hljs-title" style="color: rgb(153, 0, 0); font-weight: bold;">parseFilename</span> :: <span class="hljs-type" style="color: rgb(68, 85, 136); font-weight: bold;">String</span> -> <span class="hljs-type" style="color: rgb(68, 85, 136); font-weight: bold;">Either</span> <span class="hljs-type" style="color: rgb(68, 85, 136); font-weight: bold;">String</span> (<span class="hljs-type" style="color: rgb(68, 85, 136); font-weight: bold;">String</span>, <span class="hljs-type" style="color: rgb(68, 85, 136); font-weight: bold;">String</span>)
<span class="hljs-title" style="color: rgb(153, 0, 0); font-weight: bold;">parseFilename</span> fn = <span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">case</span> (pattern `match` fn :: [[<span class="hljs-type" style="color: rgb(68, 85, 136); font-weight: bold;">String</span>]]) <span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">of</span>
[[_, full, _, time]] -> <span class="hljs-type" style="color: rgb(68, 85, 136); font-weight: bold;">Right</span> $ (full, time)
_ -> <span class="hljs-type" style="color: rgb(68, 85, 136); font-weight: bold;">Left</span> fn
<span class="hljs-title" style="color: rgb(153, 0, 0); font-weight: bold;">pattern</span> :: <span class="hljs-type" style="color: rgb(68, 85, 136); font-weight: bold;">Regex</span>
<span class="hljs-title" style="color: rgb(153, 0, 0); font-weight: bold;">pattern</span> = makeRegex
<span class="hljs-string" style="color: rgb(221, 17, 68);">"^\\./duplicity-(full|inc|new)(-signatures)?\\.\
\([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]T[0-9][0-9][0-9][0-9][0-9][0-9]Z)\\."</span>
</code></pre>
<p style="margin: 0px 0px 1.2em ! important;">Then it runs 2-3x
faster than the profiled code.</p>
<p style="margin: 0px 0px 1.2em ! important;">The question
remains, however: why doesn’t the ghc optimizer spot this fairly
obvious loop-invariant in the non-profiled build when it does
manage to spot it in the profiled one? In other words, when I
make <code style="font-size: 0.95em; font-family: Consolas,Inconsolata,Deja Vu Sans Mono,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">pattern</code>
a local definition of <code style="font-size: 0.95em; font-family: Consolas,Inconsolata,Deja Vu Sans Mono,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">parseFilename</code>,
why isn’t it treated as a CAF that’s evaluated only once
(‘floated to the top level’)? Enabling profiling shouldn’t
change the meaning of a program.</p>
<p style="margin: 0px 0px 1.2em ! important;">I remember back in
the day having to be careful with regexes in Python to make sure
they were always precompiled outside of loops and functions, but
one of the nice things about Haskell is that one can usually let
the compiler take care of this. (Nowadays Python gets around
this by caching compiled regexes, but I prefer Haskell’s
statically-optimized approach.)</p>
<div
title="MDH:T24gMjAxNy0xMi0wNyAxMjo0OSBBTSwgSm9uYXMgU2Nob2xsIHdyb3RlOjxicj4mZ3Q7IExvb2tpbmcgYXQgdGhlIHByb2R1Y2VkIGNvcmUgb2YgYm90aCB2ZXJzaW9ucyByZXZlYWxzIHRoYXQgaW4gdGhlIHByb2ZpbGVkIGJ1aWxkIGEgY2xvc3VyZSBvZiB0eXBlIFJlZ2V4IGlzIGZsb2F0ZWQgdG8g
dG9wIGxldmVsLiBUaGUgbm9uLXByb2ZpbGVkIGJ1aWxkIGRvZXNuJ3QgZG8gdGhpcywgdGh1cyBp
dCByZWNvbXBpbGVzIHRoZSByZWdleCBmb3IgZXZlcnkgaXRlcmF0aW9uLiBUaGlzIGlzIG1vc3Qg
bGlrZWx5IHRoZSBzb3VyY2Ugb2YgdGhlIHNsb3dkb3duIG9mIHRoZSBub24tcHJvZmlsZWQgYnVp
bGQuPGJyPjxicj5UaGFua3MsIEpvbmFzLiBUaGlzIGRvZXMgaW5kZWVkIHNlZW0gdG8gYmUgdGhl
IHByb2JsZW0uIEkgY2hhbmdlZCB0aGUgY29kZSB0byB1c2UgYSBjb21waWxlZCByZWdleCAod2l0
aCBgbWFrZVJlZ2V4YCBhbmQgYG1hdGNoYCBpbnN0ZWFkIG9mIGA9fmApIGJ1dCBpbiB0aGUgbm9u
LXByb2ZpbGluZyBjYXNlIHRoZSBydW4tdGltZSBkb2Vzbid0IGltcHJvdmUgdW5sZXNzIEkgZmxv
YXQgdGhlIGNvbXBpbGVkIHJlZ2V4IG15c2VsZjo8YnI+PGJyPmBgYEhhc2tlbGw8YnI+cGFyc2VG
aWxlbmFtZSA6OiBTdHJpbmcgLSZndDsgRWl0aGVyIFN0cmluZyAoU3RyaW5nLCBTdHJpbmcpPGJy
PnBhcnNlRmlsZW5hbWUgZm4gPSBjYXNlIChwYXR0ZXJuIGBtYXRjaGAgZm4gOjogW1tTdHJpbmdd
XSkgb2Y8YnI+wqDCoMKgIFtbXywgZnVsbCwgXywgdGltZV1dIC0mZ3Q7IFJpZ2h0ICQgKGZ1bGws
IHRpbWUpPGJyPsKgwqDCoCBfIC0mZ3Q7IExlZnQgZm48YnI+PGJyPnBhdHRlcm4gOjogUmVnZXg8
YnI+cGF0dGVybiA9IG1ha2VSZWdleDxicj7CoMKgwqAgIl5cXC4vZHVwbGljaXR5LShmdWxsfGlu
Y3xuZXcpKC1zaWduYXR1cmVzKT9cXC5cPGJyPsKgwqDCoCBcKFswLTldWzAtOV1bMC05XVswLTld
WzAtOV1bMC05XVswLTldWzAtOV1UWzAtOV1bMC05XVswLTldWzAtOV1bMC05XVswLTldWilcXC4i
PGJyPmBgYDxicj48YnI+VGhlbiBpdCBydW5zIDItM3ggZmFzdGVyIHRoYW4gdGhlIHByb2ZpbGVk
IGNvZGUuPGJyPjxicj5UaGUgcXVlc3Rpb24gcmVtYWlucywgaG93ZXZlcjogd2h5IGRvZXNuJ3Qg
dGhlIGdoYyBvcHRpbWl6ZXIgc3BvdCB0aGlzIGZhaXJseSBvYnZpb3VzIGxvb3AtaW52YXJpYW50
IGluIHRoZSBub24tcHJvZmlsZWQgYnVpbGQgd2hlbiBpdCBkb2VzIG1hbmFnZSB0byBzcG90IGl0
IGluIHRoZSBwcm9maWxlZCBvbmU/IEluIG90aGVyIHdvcmRzLCB3aGVuIEkgbWFrZSBgcGF0dGVy
bmAgYSBsb2NhbCBkZWZpbml0aW9uIG9mIGBwYXJzZUZpbGVuYW1lYCwgd2h5IGlzbid0IGl0IHRy
ZWF0ZWQgYXMgYSBDQUYgdGhhdCdzIGV2YWx1YXRlZCBvbmx5IG9uY2UgKCdmbG9hdGVkIHRvIHRo
ZSB0b3AgbGV2ZWwnKT8gRW5hYmxpbmcgcHJvZmlsaW5nIHNob3VsZG4ndCBjaGFuZ2UgdGhlIG1l
YW5pbmcgb2YgYSBwcm9ncmFtLjxicj48YnI+SSByZW1lbWJlciBiYWNrIGluIHRoZSBkYXkgaGF2
aW5nIHRvIGJlIGNhcmVmdWwgd2l0aCByZWdleGVzIGluIFB5dGhvbiB0byBtYWtlIHN1cmUgdGhl
eSB3ZXJlIGFsd2F5cyBwcmVjb21waWxlZCBvdXRzaWRlIG9mIGxvb3BzIGFuZCBmdW5jdGlvbnMs
IGJ1dCBvbmUgb2YgdGhlIG5pY2UgdGhpbmdzIGFib3V0IEhhc2tlbGwgaXMgdGhhdCBvbmUgY2Fu
IHVzdWFsbHkgbGV0IHRoZSBjb21waWxlciB0YWtlIGNhcmUgb2YgdGhpcy4gKE5vd2FkYXlzIFB5
dGhvbiBnZXRzIGFyb3VuZCB0aGlzIGJ5IGNhY2hpbmcgY29tcGlsZWQgcmVnZXhlcywgYnV0IEkg
cHJlZmVyIEhhc2tlbGwncyBzdGF0aWNhbGx5LW9wdGltaXplZCBhcHByb2FjaC4pPGJyPg=="
style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0;"></div>
</div>
</body>
</html>