grauzone wrote:
Andrei Alexandrescu wrote:
I was thinking of solving these issues by keeping an LRU (Least Recently Used) cache inside the implementation of ~=. The LRU would only have a few entries (4-8) and would store the parameters of the last ~= calls, and their cached capacities.

Sounds like a bad hack, but at least it would solve the issue about overwritten slices.

But for some uses of array appending, you had to use a library based "Appender" (or whatever you have in Phobos 2):

class Something {
   T[] data;
   void add(T x) {
     data ~= x; //chances that data are in the cache are minimal
   }
}

There's no "cache locality" or anything, but obviously you still would like to have efficient appender behavior.

Why is there no cache locality?

Also look at this:

string[] t;
t ~= somefunction();
t ~= someotherfunction();

Chances are high that those functions will remove "t" from the cache, and it would all be inefficient again. Nothing solved!

Why are there chances those functions will remove "t" from the cache? For it to become a performance problem, there must be a loop with nine or more round-robin appends. When that does happen, yes, appends will become slower. (We may be able to make that better by using random eviction.)

Now you could try to make the cache function local to solve this issue. Whenever a function contains the ~= operator, the compiler allocates a "cache" struct, and the ~= operator passes a hidden pointer to it to the runtime.

But that wouldn't work if you want pass slices to other functions and to append to them (but it would still be safe, I guess?).

Looks like these performance hacks just don't work out.

Caches have a long and solid history of working. You'd have a very hard time convincing me that a cache that directly addresses a performance problem is a hack.

It'd be so much simpler to make "a~=b;" equivalent to "a=a~b;". Then there's no "mystery" about the performance of the ~= operator. You can explain everyone: "yes, this allocates; if you want performance, use ArrayAppender". Hey, you could alias this ArrayAppender type to something like T[new] to make it feel more natural. But then, we're at the beginning again.

I think making ~= faster is worth pursuing.


Andrei

Reply via email to