On Wed, Apr 6, 2016 at 8:12 AM, Martin Karlgren marty@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