December 05, 2007 Re: Memory allocation in D (noob question) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | On 12/5/07, Sean Kelly <sean@f4.ca> wrote:
> Or the runtime could be changed to always copy. However, it would absolutely murder application performance for something like this:
>
> char[] buf;
> for( int i = 0; i < 1_000_000; ++i )
> buf ~= 'a';
It would, /unless/ we had a vector type (a C++ std::vector, not a math vector). Java has something similar, I believe - immutable strings, but also a StringBuffer type. (I could be wrong about the details). Anyway, the point is, you'd just rewrite the above loop as:
Vector!(char) buf;
for( int i = 0; i < 1_000_000; ++i )
buf ~= 'a';
//
// and when you're done
//
return buf.toArray();
That sort of thing.
|
December 05, 2007 Re: Memory allocation in D (noob question) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | On Wed, 05 Dec 2007 16:18:46 +0000, Regan Heath wrote: > [example pasted again for clarity] > > > string ab = "ab".idup; > > string a = ab[0..1]; > > a ~= "c"; > > writefln("ab = ",ab); // also outputs "ac" However, this is fine ... string ab = "ab"; string a = ab[0..1]; a ~= "c"; writefln("ab = ",ab); // outputs "ab" writefln("a = ",a); // outputs "ac" So it seems that the '.idup' property is affecting things. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell |
December 05, 2007 Re: Memory allocation in D (noob question) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | "Derek Parnell" wrote
> On Wed, 05 Dec 2007 16:18:46 +0000, Regan Heath wrote:
>
>> [example pasted again for clarity]
>>
>> > string ab = "ab".idup;
>> > string a = ab[0..1];
>> > a ~= "c";
>> > writefln("ab = ",ab); // also outputs "ac"
>
> However, this is fine ...
>
> string ab = "ab";
> string a = ab[0..1];
> a ~= "c";
> writefln("ab = ",ab); // outputs "ab"
> writefln("a = ",a); // outputs "ac"
>
> So it seems that the '.idup' property is affecting things.
Yes, I noticed that too. However, it's simply the non-deterministic behavior of the ~= operator that is causing this. For literal strings, I suspect they are not allocated by the GC, and so the GC can't extend them, so the normal behavior kicks in. But idup is supposed to give me an invariant array. The code is still changing invariant data...
-Steve
|
December 05, 2007 Re: Memory allocation in D (noob question) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote: > However, this is fine ... > > string ab = "ab"; > string a = ab[0..1]; > a ~= "c"; > writefln("ab = ",ab); // outputs "ab" > writefln("a = ",a); // outputs "ac" > > So it seems that the '.idup' property is affecting things. It's probably just a side effect of the fact that string literals are immutable. The compiler knows that it has to reallocate when appending to it, I guess? import std.stdio; void main() { int[] ab = [0, 1]; int[] a = ab[0..1]; a ~= 2; writefln(ab); writefln(a); } -- E-mail address: matti.niemenmaa+news, domain is iki (DOT) fi |
December 06, 2007 Re: Memory allocation in D (noob question) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matti Niemenmaa | Matti Niemenmaa wrote:
> Derek Parnell wrote:
>> However, this is fine ...
>>
>> string ab = "ab";
>> string a = ab[0..1];
>> a ~= "c";
>> writefln("ab = ",ab); // outputs "ab"
>> writefln("a = ",a); // outputs "ac"
>>
>> So it seems that the '.idup' property is affecting things.
>
> It's probably just a side effect of the fact that string literals are immutable.
> The compiler knows that it has to reallocate when appending to it, I guess?
I suspect you're right. I think the reason is that a string literal is not allocated in the same way as the result from idup and maybe does not appear in the GC's list of memory blocks. So, if the GC doesn't know about it, the GC does not reallocate but instead copies.
Regan
|
December 06, 2007 Re: Memory allocation in D (noob question) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer wrote:
> "Derek Parnell" wrote
>> On Wed, 05 Dec 2007 16:18:46 +0000, Regan Heath wrote:
>>
>>> [example pasted again for clarity]
>>>
>>> > string ab = "ab".idup;
>>> > string a = ab[0..1];
>>> > a ~= "c";
>>> > writefln("ab = ",ab); // also outputs "ac"
>> However, this is fine ...
>>
>> string ab = "ab";
>> string a = ab[0..1];
>> a ~= "c";
>> writefln("ab = ",ab); // outputs "ab"
>> writefln("a = ",a); // outputs "ac"
>>
>> So it seems that the '.idup' property is affecting things.
>
> Yes, I noticed that too. However, it's simply the non-deterministic behavior of the ~= operator that is causing this. For literal strings, I suspect they are not allocated by the GC, and so the GC can't extend them, so the normal behavior kicks in. But idup is supposed to give me an invariant array. The code is still changing invariant data...
To me, all the behaviour is "normal" ;)
I think you're right about the reason it copies in this case. I wonder if the solution is for the GC to keep a seperate list of memory blocks which are invariant... then on reallocate it simply ignores this list - resulting in the same behavior as the string literal case.
Regan
|
Copyright © 1999-2021 by the D Language Foundation