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).