On Wed, Apr 6, 2016 at 8:12 AM, Martin Karlgren <ma...@roxen.com> wrote:
> Having realised the benefits of functional programming, I’ve been quite 
> annoyed by the rumour of how expensive function calls are in Pike. I decided 
> to look into f_map and could see how much seemingly unnecessary work it does 
> when it calls apply_svalue once for each entry in the array – it should be 
> possible to reuse the pike_frame if it’s about to be thrown away after the 
> function call (if it has other refs on the other hand, it can’t be reused – 
> it’s probably used as a scope in some other frame).
>

Crucially, you're looking at optimizing this code.

  float gmap = gauge {
      array res = map (base, lambda(int i) { return i + 2; });
    };

For comparison, Python handles this with a list comprehension, replacing this:

res = list(map(lambda i: i + 2, base))

with this:

res = [i + 2 for i in base]

This compiles to a single operation that loops over the base and
constructs a new list.

I think your optimization is a good one to do (although I can't speak
to Pike's internals to prove correctness), but what I'd like to see is
a way to not need the lambda function at all. Automap syntax is great
for simple calls like this, so I added it to your timing test:

  float gautomap = gauge {
      array res = base[*] + 2;
    };

Without the optimization:

$ bin/pike ../mapspeed.pike
automap: 0.230016378
map: 0.327757117
array index: 0.256829669
array append: 0.339447457

With optimization:

$ bin/pike ../mapspeed.pike
automap: 0.256595633
map: 0.189304826
array index: 0.24930893
array append: 0.314897908

Interestingly, your optimization actually comes out faster than
automap. I'm not surprised it's faster than array append, and even the
array index one (it's quicker to do the whole job in C), but automap
would normally be my go-to answer for stuff like this.

So yeah, I'd support this 100%, unless it can be proven to be
incorrect in some way.

ChrisA

Reply via email to