On 02/03/12 13:06, Jonathan M Davis wrote:
> On Friday, February 03, 2012 11:08:54 Artur Skawina wrote:
>> BTW, scope should have been the default for *all* reference type function
>> arguments, with an explicit modifier, say "esc", required to let the thing
>> escape. It's an all-or-nothing thing, just like immutable strings - not
>> using it everywhere is painful, but once you switch everything over you get
>> the benefits.
> 
> That would destroy slicing. I'm firmly of the opinion that scope should be 
> used 
> sparingly.

Well, not doing it destroys performance. [1] It's a trade-off. Also, i don't
know if "destroy slicing" is accurate.

Things like 'string f(string s) { return s[1..$]; }' needs to continue to work;
the object does not really "escape" from the POV of f(), but the caller has to
assume it's not dead after returning from the function. Doing this by default 
for
any functions returning refs that could potentially hold on to the passed object
would make things work. For the cases that where the called function knows that 
it will always return unique objects the signature could look like
'new string f(string s);', but that's only an optimization.

Any other problematic slicing use, that i'm not thinking of right now?

artur


[1] I had a case, where turning on logging in some code made the program 
unusable,
because instead of IIRC ~40s it took 40+ minutes, at which point i gave up and
killed it... The profile looked like this:

37.62%  uint gc.gcx.Gcx.fullcollect(void*)
20.47%  uint gc.gcbits.GCBits.test(uint)
13.80%  uint gc.gcbits.GCBits.testSet(uint)
10.15%  pure nothrow @safe bool std.uni.isGraphical(dchar)
 3.33%  _D3std5array17__T8AppenderTAyaZ8Appender10__T3putTwZ3putMF
 2.78%  0x11025a        
 2.13%  _D3std6format65__T13formatElementTS3std5array17__T8Appende
 1.64%  _D3std6format56__T10formatCharTS3std5array17__T8AppenderTA
 1.37%  pure @safe uint std.utf.encode(ref char[4], dchar)
 0.88%  void* gc.gcx.GC.malloc(uint, uint, uint*)
 0.50%  pure nothrow @safe bool std.uni.binarySearch2(dchar, 
immutable(dchar[2][]))
 0.45%  void gc.gcbits.GCBits.set(uint)
 0.37%  void gc.gcbits.GCBits.clear(uint)
 0.34%  __divdi3

That shows several problems, but even after fixing the obvious ones (inlining
GCBits, making std.uni.isGraphical sane (this, btw, reduced its cost to ~1%))
GC still takes up most of time (not remembering the details, but certainly >50%,
it could have been >80%).
Some slowdown from the IO and formatting is expected, but spending most cycles
on GC is not reasonable, when most objects never leave the scope (in this case
it was just strings passed to writeln etc IIRC).

Reply via email to