Re: Cost of .dup vs. instantiation

2014-05-29 Thread Chris via Digitalmars-d-learn

On Wednesday, 28 May 2014 at 17:33:19 UTC, monarch_dodra wrote:

On Wednesday, 28 May 2014 at 14:36:25 UTC, Chris wrote:
I use Appender to fill an array. The Appender is a class 
variable and is not instantiated with each function call to 
save instantiation. However, the return value or the function 
must be dup'ed, like so:


Appender!(MyType[]) append;
public auto doSomething() {
 scope (exit) { // clear append }
 // ... do something
 append ~= item;
 return (append.data).dup
}

My question is whether I save anything with Appender as a 
class variable here. I have to .dup the return value (+ clear 
the Appender). If I had a new Appender with each function 
call, it might be just as good.


public auto doSomething() {
 Appender!(MyType[]) append;
 // 
 return append.data.
}

Right or wrong?


You might save a little because you avoid the cost of growing 
your appender repeatedly: Once the appender has come to 
maturity, it will very likely stop growing.


At that point, you only pay for *1* allocation per call to 
doSomething. Further advantages include:

 - dup has APPENDABLE info (whereas appender.data does not).
 - less wasted memory: dup uses no more memory than it has to, 
whereas Appender may over-allocate, depending on how you fill 
it.


The downside to your approach is that you keep a handle on a 
buffer that can grow, but never shrink. If a at a certain 
point, you have to process some particularly large input, then 
you'll consume excessive amounts of memory.


monarch_dodra:
Hm. This last point might be an issue. If I process a large input 
(text in this case) then I might run into trouble with append 
as a class variable. I also had a weird bug, because I didn't 
clear the memory for overwrite.


TheFlyingFiddle:
append is a class variable in _my_ program, not Appender, like 
so:


class A {
  Appender!(MyType[]) append;
  // ...
}


Re: Cost of .dup vs. instantiation

2014-05-29 Thread monarch_dodra via Digitalmars-d-learn

On Thursday, 29 May 2014 at 08:49:10 UTC, Chris wrote:

monarch_dodra:
Hm. This last point might be an issue. If I process a large 
input (text in this case) then I might run into trouble with 
append as a class variable. I also had a weird bug, because I 
didn't clear the memory for overwrite.


You can always implement an upper bound approach, where if your 
input data becomes larger than a certain size, you return the 
data directly, and reset your appender. EG:


Appender!(MyType[]) append;
public auto doSomething() {
  scope (failure) { append.clear; }
  // ... do something
  append ~= item;
  MyType[] ret;
  if (append.data.length  10_000)
  {
ret = append.data).dup;
append.clear; //clears buffer, keeps memory.
  }
  else
  {
ret = append.data;
append = appender!(MyType[])(); //jettison old appender data.
  }
  return ret;
}


Re: Cost of .dup vs. instantiation

2014-05-29 Thread Chris via Digitalmars-d-learn

On Thursday, 29 May 2014 at 12:04:35 UTC, monarch_dodra wrote:

On Thursday, 29 May 2014 at 08:49:10 UTC, Chris wrote:

monarch_dodra:
Hm. This last point might be an issue. If I process a large 
input (text in this case) then I might run into trouble with 
append as a class variable. I also had a weird bug, because 
I didn't clear the memory for overwrite.


You can always implement an upper bound approach, where if 
your input data becomes larger than a certain size, you return 
the data directly, and reset your appender. EG:


Appender!(MyType[]) append;
public auto doSomething() {
  scope (failure) { append.clear; }
  // ... do something
  append ~= item;
  MyType[] ret;
  if (append.data.length  10_000)
  {
ret = append.data).dup;
append.clear; //clears buffer, keeps memory.
  }
  else
  {
ret = append.data;
append = appender!(MyType[])(); //jettison old appender 
data.

  }
  return ret;
}


Yes, you're right, this is a possible solution. However, I don't 
feel good about keeping memory I don't need. This might be a 
problem when the code will finally be ported to mobile devices.


I benchmarked the two implementations (class variable vs local 
variable) and the performance (i.e. speed) remains the same.


Cost of .dup vs. instantiation

2014-05-28 Thread Chris via Digitalmars-d-learn
I use Appender to fill an array. The Appender is a class variable 
and is not instantiated with each function call to save 
instantiation. However, the return value or the function must be 
dup'ed, like so:


Appender!(MyType[]) append;
public auto doSomething() {
  scope (exit) { // clear append }
  // ... do something
  append ~= item;
  return (append.data).dup
}

My question is whether I save anything with Appender as a class 
variable here. I have to .dup the return value (+ clear the 
Appender). If I had a new Appender with each function call, it 
might be just as good.


public auto doSomething() {
  Appender!(MyType[]) append;
  // 
  return append.data.
}

Right or wrong?



Re: Cost of .dup vs. instantiation

2014-05-28 Thread monarch_dodra via Digitalmars-d-learn

On Wednesday, 28 May 2014 at 14:36:25 UTC, Chris wrote:
I use Appender to fill an array. The Appender is a class 
variable and is not instantiated with each function call to 
save instantiation. However, the return value or the function 
must be dup'ed, like so:


Appender!(MyType[]) append;
public auto doSomething() {
  scope (exit) { // clear append }
  // ... do something
  append ~= item;
  return (append.data).dup
}

My question is whether I save anything with Appender as a class 
variable here. I have to .dup the return value (+ clear the 
Appender). If I had a new Appender with each function call, it 
might be just as good.


public auto doSomething() {
  Appender!(MyType[]) append;
  // 
  return append.data.
}

Right or wrong?


You might save a little because you avoid the cost of growing 
your appender repeatedly: Once the appender has come to 
maturity, it will very likely stop growing.


At that point, you only pay for *1* allocation per call to 
doSomething. Further advantages include:

 - dup has APPENDABLE info (whereas appender.data does not).
 - less wasted memory: dup uses no more memory than it has to, 
whereas Appender may over-allocate, depending on how you fill it.


The downside to your approach is that you keep a handle on a 
buffer that can grow, but never shrink. If a at a certain point, 
you have to process some particularly large input, then you'll 
consume excessive amounts of memory.


Re: Cost of .dup vs. instantiation

2014-05-28 Thread TheFlyingFiddle via Digitalmars-d-learn

On Wednesday, 28 May 2014 at 14:36:25 UTC, Chris wrote:
I use Appender to fill an array. The Appender is a class 
variable and is not instantiated with each function call to 
save instantiation. However, the return value or the function 
must be dup'ed, like so:


Appender!(MyType[]) append;
public auto doSomething() {
  scope (exit) { // clear append }
  // ... do something
  append ~= item;
  return (append.data).dup
}

My question is whether I save anything with Appender as a class 
variable here. I have to .dup the return value (+ clear the 
Appender). If I had a new Appender with each function call, it 
might be just as good.


public auto doSomething() {
  Appender!(MyType[]) append;
  // 
  return append.data.
}

Right or wrong?


When it comes to optimizations it's hard to say. Benchmarking is 
better than relying advice/opinions on the internet in any case.


That being said i doubt that the instantiation cost of the 
Appender is relevant. (Btw the appender is not a class variable! 
It is a struct with reference semantics). Reusing an appender is 
more for those cases where you want to reuse the underlying 
memory of the appender itself.