<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2015-01-20 1:29 GMT+01:00 Eliot Miranda <span dir="ltr">&lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><span class="">On Mon, Jan 19, 2015 at 1:31 PM, Nicolas Cellier <span dir="ltr">&lt;<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div>Hi Tobias,<br>are you aware of CurrentReadOnlySourceFiles cacheDuring: [...]<br></div>This is to workaround the readOnlyCopy used for thread safety which is the main killer of performance...<br></div></blockquote><div><br></div></span><div>IMO this is a bug.  We should simply have a single read-only copy of each sources file and modify the debugger to either save and restore the state of a read-only copy around accessing source, or use its own read-only copy (except that the latter approach breaks when one debugs the debugger).  The difference in performance between using CurrentReadOnlySourceFiles cacheDuring: [...] and not in anything that accesses source is huge.  And CurrentReadOnlySourceFiles cacheDuring: [...] is a /lot/ of verbiage to type in doits, and a sign that something is wrong.</div></div></div></div></blockquote><div><br></div><div>Yes it&#39;s smells... It&#39;s not our business, an encapsulation is missing.<br> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">2015-01-19 22:10 GMT+01:00 Tobias Pape <span dir="ltr">&lt;<a href="mailto:Das.Linux@gmx.de" target="_blank">Das.Linux@gmx.de</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>
On 19.01.2015, at 21:51, Levente Uzonyi &lt;<a href="mailto:leves@elte.hu" target="_blank">leves@elte.hu</a>&gt; wrote:<br>
<br>
&gt; On Mon, 19 Jan 2015, Tobias Pape wrote:<br>
&gt;<br>
&gt;&gt;<br>
&gt;&gt; On 19.01.2015, at 18:34, Chris Muller &lt;<a href="mailto:asqueaker@gmail.com" target="_blank">asqueaker@gmail.com</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt;&gt; On Mon, Jan 19, 2015 at 6:45 AM, Tobias Pape &lt;<a href="mailto:Das.Linux@gmx.de" target="_blank">Das.Linux@gmx.de</a>&gt; wrote:<br>
&gt;&gt;&gt; Hi all,<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; We store method source _solely_ in files (.sources/.changes).<br>
&gt;&gt;&gt; Why? We have means to attach it to Compiled methods, in fact, more than one:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; CompiledMethod allInstances size. &quot;57766.&quot;<br>
&gt;&gt;&gt; CompiledMethod allInstances count: [:m | m properties includesKey: #source].  &quot;0.&quot;<br>
&gt;&gt;&gt; CompiledMethod allInstances count: [:m | m trailer sourceCode notNil]. &quot;0.&quot;<br>
&gt;&gt;&gt; CompiledMethod allInstances count: [:m | m trailer hasSourcePointer]. &quot;57700.&quot;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; &quot; also interesting &quot;<br>
&gt;&gt;&gt; (CompiledMethod allInstances collect: [:m | m trailer kind] as: Bag) sortedCounts<br>
&gt;&gt;&gt; {57701-&gt;#SourcePointer . 65-&gt;#NoTrailer . 14-&gt;#TempsNamesQCompress . 2-&gt;#TempsNamesZip}<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; When doing some analysis on source code, it is a pain to _either_<br>
&gt;&gt;&gt; always go to disk for the source _or_ cache the code myself (which may<br>
&gt;&gt;&gt; get out of sync sooon).<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; If you&#39;re sending messages instead of viewing private innards, why is it a pain?<br>
&gt;&gt;<br>
&gt;&gt; What do you mean?<br>
&gt;&gt;<br>
&gt;&gt; Calling getSource on a CM goes 300km to disk instead of 1m to memory (metaphorically spoken)<br>
&gt;&gt; and when I do analysis on source code I typically do stuff like that a lot.<br>
&gt;&gt; And as developer I really dislike that I have to choose between either<br>
&gt;&gt;<br>
&gt;&gt; a) bad performance due to excessive IO (yes I want to access the source a lot)<br>
&gt;&gt; b) caching things myself when already two ways of storing them are available.<br>
&gt;<br>
&gt; On today&#39;s machines you don&#39;t have to. Once you read the data from the disk, it&#39;ll be cached in memory. It would be faster to access the sources, if they were stored in a trailer, but that would bump the image size by about 15 MB (uncompressed), or 9 MB (compressed):<br>
&gt;<br>
<br>
I understand. But for a development image, I&#39;d take that burden.<br>
<br>
&gt; | size compressedSize |<br>
&gt; size := compressedSize := 0.<br>
&gt; CurrentReadOnlySourceFiles cacheDuring: [<br>
&gt;       SystemNavigation default allSelectorsAndMethodsDo: [ :behavior :selector :method |<br>
&gt;               | string compressed |<br>
&gt;               string := method getSource asString.<br>
&gt;               compressed := string squeakToUtf8 zipped.<br>
&gt;               size := size + string byteSize + ((string size &gt; 255) asBit + 1 * 4).<br>
&gt;               compressedSize := compressedSize + compressed byteSize + ((compressed size &gt; 255) asBit + 1 * 4) ] ].<br>
&gt; { size. compressedSize }.<br>
&gt;<br>
&gt; &quot;==&gt; #(15003880 9057408)&quot;<br>
<br>
<br>
What I am actually wondering about,<br>
there are two completely different ways to _access_ source stored in the image<br>
but no way to actually _store_ it there.<br>
<br>
&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;  Can&#39;t we just save the source code either via trailer or properties<br>
&gt;&gt;&gt; on first access?<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; -1.  Why do I want all of those String&#39;s in my image?<br>
&gt;&gt;<br>
&gt;&gt; To do stuff to them.<br>
&gt;&gt; Like, analysing how many dots are in them, or how often someone crafts a Symbol.<br>
&gt;&gt; Analysis stuff.<br>
&gt;&gt; Currently, I have a separate structure that holds onto the code once retrieved<br>
&gt;&gt; from disk. But once the method change (eg, recompilation) I have to first detect,<br>
&gt;&gt; that it happened, and second flush and refill this cache. I find this tiresome.<br>
&gt;<br>
&gt; Do you flush your cache selectively?<br>
<br>
No, I can&#39;t for reasons :)<br>
<br>
&gt;<br>
&gt; Scanning all source code for a given pattern takes less than a second (~800 ms) on my machine. What&#39;s your performance goal?<br>
<br>
I have ~15.000 Methods that I have to compare line by line against each other.<br>
Doing that by going to the filesystem just kills it.<br>
<br>
<br>
Best<br>
<span><font color="#888888">        -Tobias</font></span></blockquote></div></div></div></div></blockquote></div></div></div><span class="HOEnZb"><font color="#888888">-- <br><div>best,<div>Eliot</div></div>
</font></span></div></div>
<br><br>
<br></blockquote></div><br></div></div>