Karim Belabas on Tue, 24 Jun 2025 14:03:52 +0200 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
Re: a remark / feature request about listpop |
* M. F. Hasler [2025-06-20 23:55]: > Allowing negative indices to get elements counted from the back would > also be a -- probably even better -- alternative, of course. This would slow down all accesses to GP array elements, as well as making obvious mistakes (non-positive array indices) harder to detect. The use case is not important enough for this. > [I sometimes saw (and maybe even used, unofficially) a construction like > v[-1..-1][1], but I think that's terrible and really looks desperate. > It could for example be motivated if you don't have the vector stored in a > variable v, but just, e.g., the result of a function, like > computeSolution(args)[-1..-1][1] to get just the last element. But yes, > it's terrible, I agree.] I'm happy to report that v[-1..-1][1] is about 35% slower than v[#v]. Don't use that, ever. :-) About not storing the return value in a variable, you have a point. But (unless you're extra careful) chances are the GP memory model are already forcing copies of that return value somewhere in the function body. The best place to handle such concerns is currently computeSolution() itself: computeSolution(args, only_last = 0) etc. Cheers, K.B. P.S. To have an idea of what GP is *really* doing behind the scenes, you can have fun with install(closure_disassemble, vG); For instance, these two trivial routines are functionally equivalent: weightedmean(x, y)= { my(N = sum(i=1,#y, y[i])); sum(i=1,#x, x[i]*y[i]) / N * 1.; } weightedmean2(x, y)= sum(i=1,#x, x[i]*y[i]) / sum(i=1,#y, y[i]) * 1.; But the GP compiler currently handles the second one in a (marginally) more efficient way: ? closure_disassemble(weightedmean2) 00001 getargs 2 00002 pushstoi 1 00003 pushlex -2 00004 calllong #_ 00005 stoi 00006 pushgen 1 00007 pushlong 0 00008 callgen sum 00009 pushstoi 1 00010 pushlex -1 00011 calllong #_ 00012 stoi 00013 pushgen 2 00014 pushlong 0 00015 callgen sum 00016 callgen2 _/_ 00017 pushreal 3 00018 callgen2 _*_ ? closure_disassemble(weightedmean) 00001 getargs 2 00002 newframe 1 \\ extra 00003 pushstoi 1 00004 pushlex -2 00005 calllong #_ 00006 stoi 00007 pushgen 1 00008 pushlong 0 00009 callgen sum 00010 storelex -1 \\ extra 00011 pushstoi 1 00012 pushlex -3 00013 calllong #_ 00014 stoi 00015 pushgen 2 00016 pushlong 0 00017 callgen sum 00018 pushlex -1 \\ extra 00019 callgen2 _/_ 00020 pushreal 3 00021 callgen2 _*_ -- Pr. Karim Belabas, U. Bordeaux, Vice-président en charge du Numérique Institut de Mathématiques de Bordeaux UMR 5251 - (+33) 05 40 00 29 77 http://www.math.u-bordeaux.fr/~kbelabas/