Hi Levente,<br><br><div class="gmail_quote">On Tue, Jun 22, 2010 at 2:28 PM, Levente Uzonyi <span dir="ltr">&lt;<a href="mailto:leves@elte.hu">leves@elte.hu</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Hi,<br>
<br>
I was curious how much speedup Cog gives when the code has only a few message sends, so I ran the following &quot;benchmark&quot;:<br>
<br>
| s1 s2 |<br>
Smalltalk garbageCollect.<br>
s1 := String streamContents: [ :stream |<br>
        1000 timesRepeat: [<br>
                &#39;aab&#39; do: [ :e | stream nextPut: e; cr ] ] ].<br>
s2 := String streamContents: [ :stream |<br>
        1000 timesRepeat: [<br>
                &#39;abb&#39; do: [ :e | stream nextPut: e; cr ] ] ].<br>
[ TextDiffBuilder from: s1 to: s2 ] timeToRun.<br>
<br>
The above pattern makes TextDiffBuilder &gt;&gt; #lcsFor:and: run for a while. My results are a bit surprising:<br>
CogVM: 2914<br>
SqueakVM: 1900<br>
<br>
MessageTally shows that (I wonder if it&#39;s accurate with Cog at all) CogVM&#39;s garbage collector is a bit better, but it runs the code slower than SqueakVM:<br>
<br>
CogVM:<br>
**Leaves**<br>
60.6% {1886ms} TextDiffBuilder&gt;&gt;lcsFor:and:<br>
36.2% {1127ms} DiffElement&gt;&gt;=<br>
1.8% {56ms} ByteString(String)&gt;&gt;=<br>
<br>
**GCs**<br>
        full                    1 totalling 153ms (5.0% uptime), avg 153.0ms<br>
        incr            21 totalling 76ms (2.0% uptime), avg 4.0ms<br>
        tenures         13 (avg 1 GCs/tenure)<br>
        root table      0 overflows<br>
<br>
SqueakVM:<br>
**Leaves**<br>
46.8% {888ms} TextDiffBuilder&gt;&gt;lcsFor:and:<br>
35.3% {670ms} DiffElement&gt;&gt;=<br>
9.8% {186ms} ByteString(String)&gt;&gt;compare:with:collated:<br>
6.9% {131ms} ByteString(String)&gt;&gt;=<br>
<br>
**GCs**<br>
        full                    3 totalling 254ms (13.0% uptime), avg 85.0ms<br>
        incr            301 totalling 110ms (6.0% uptime), avg 0.0ms<br>
        tenures         272 (avg 1 GCs/tenure)<br>
        root table      0 overflows<br>
<br>
Is Cog slower because #to:do: loops are not optimized, or is there some other reason for the slowdown?<br></blockquote><div><br></div><div>I can&#39;t say for sure without profiling (you&#39;ll find a good VM profiler QVMProfiler in the image in the tarball, which as yet works on MacOS only).</div>
<div>But I expect that the reason is the cost of invoking interpreter primitives from machine code.  Cog only implements a few primitives in machine code (arithmetic, at: &amp; block value) and for all others (e.g. nextPut: above) it executes the interpreter primitives.  lcsFor:and: uses at:put: heavily and Cog is using the interpreter version.  But the cost of invoking an interpreter primitive from machine code is higher than invoking it from the interpreter because of the system-call-like glue between the machine-code stack pages and the C stack on which the interpreter primitive runs.</div>
<div><br></div><div>Three primitives that are currently interpreter primitives but must be implemented in machine code for better performance are new/basicNew, new:/basicNew: and at:put:.  I&#39;ve avoided implementing these in machine code because the object representation is so complex and am instead about to start work on a simpler object representation.  When I have that I&#39;ll implement these primitives and then the speed difference should tilt the other way.</div>
<div><br></div><div>Of course if anyone would like to implement these in the context of the current object representation be my guest and report back asap...</div><div><br></div><div>best</div><div>Eliot</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<font color="#888888">
<br>
<br>
Levente<br>
<br>
</font></blockquote></div><br>