| 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/