Math.minmax

classic Classic list List threaded Threaded
18 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Math.minmax

Xavier Stouder

Had a relatively simple idea tonight : https://github.com/Xstoudi/proposal-math-minmax

Please take a look, comment and tell me if you’re an interested tc39 champion.

 


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Math.minmax

Florian Bösch
  • Improve performance

I doubt that this sequence of calls:

min = Math.min(min, value)
max = Math.max(max, value)

Is slower than this:

[min,max] = Math.minmax([min,max,value])

 Because while the former can get inlined by JIT, the latter can't, and on top, it allocates 2 objects which then have to be GC'ed.

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Math.minmax

T.J. Crowder-2
On Thu, Jun 29, 2017 at 9:19 AM, Florian Bösch <[hidden email]> wrote:
> > Improve performance
>
> I doubt that this sequence of calls:
>
> min = Math.min(min, value)
> max = Math.max(max, value)
>
>
> Is slower than this:
>
> [min,max] = Math.minmax([min,max,value])
>
> Because while the former can get inlined by JIT, the latter can't,
> and on top, it allocates 2 objects which then have to be GC'ed.

I was going to make that very point, backed by a jsPerf, but the jsPerf doesn't back it up: https://jsperf.com/two-calls-vs-one-returning-array It says the minmax is faster on a 10-entry array (it reports the separate calls as 46-48% slower on V8 and SpiderMonkey).

Now, that's comparing making calls to functions defined in userland, not ones provided by the engine, so that's an important difference. And there's basically no memory pressure, whereas in real life there may be. And it's a synthetic benchmark. But there we are.

-- T.J. Crowder


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Math.minmax

Florian Bösch
A proper test would do this on a few hundred million elements interrupted every 16.6ms with a RAF so as to give the GC a chance to run and run about 30 seconds so as to trigger at least a couple GC cycles.

On Thu, Jun 29, 2017 at 10:49 AM, T.J. Crowder <[hidden email]> wrote:
On Thu, Jun 29, 2017 at 9:19 AM, Florian Bösch <[hidden email]> wrote:
> > Improve performance
>
> I doubt that this sequence of calls:
>
> min = Math.min(min, value)
> max = Math.max(max, value)
>
>
> Is slower than this:
>
> [min,max] = Math.minmax([min,max,value])
>
> Because while the former can get inlined by JIT, the latter can't,
> and on top, it allocates 2 objects which then have to be GC'ed.

I was going to make that very point, backed by a jsPerf, but the jsPerf doesn't back it up: https://jsperf.com/two-calls-vs-one-returning-array It says the minmax is faster on a 10-entry array (it reports the separate calls as 46-48% slower on V8 and SpiderMonkey).

Now, that's comparing making calls to functions defined in userland, not ones provided by the engine, so that's an important difference. And there's basically no memory pressure, whereas in real life there may be. And it's a synthetic benchmark. But there we are.

-- T.J. Crowder



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Re: Math.minmax

Xavier Stouder
In reply to this post by Xavier Stouder

The results is expected (in the naive way at least). You loop just one time instead of two on the array.

 

Now I’m not enough involved in how JS engines work at a lower level to make more hypothesis.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Math.minmax

Boris Zbarsky
In reply to this post by T.J. Crowder-2
On 6/29/17 1:49 AM, T.J. Crowder wrote:
> I was going to make that very point, backed by a jsPerf, but the jsPerf
> doesn't back it up: https://jsperf.com/two-calls-vs-one-returning-array
> It says the minmax is faster on a 10-entry array (it reports the
> separate calls as 46-48% slower on V8 and SpiderMonkey).

See https://jsperf.com/two-calls-vs-one-no-destructuring/1 which is the
same as the above-linked testcase but doesn't do destructuring of an
array into an arglist and the collapsing of an arglist into an array for
every call.  In that one the two-call version is in fact faster.

That is, the cost of allocating and filling the two-element return value
array is much smaller than the cost of allocating and filling the
20-element array.  Since the two-call testcase in
https://jsperf.com/two-calls-vs-one-returning-array does the latter
twice, it ends up slower than the version that only does it once.

-Boris
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Math.minmax

T.J. Crowder-2
On Fri, Jun 30, 2017 at 7:53 AM, Boris Zbarsky <[hidden email]> wrote:
On 6/29/17 1:49 AM, T.J. Crowder wrote:
I was going to make that very point, backed by a jsPerf, but the jsPerf
doesn't back it up: https://jsperf.com/two-calls-vs-one-returning-array
It says the minmax is faster on a 10-entry array (it reports the
separate calls as 46-48% slower on V8 and SpiderMonkey).

See https://jsperf.com/two-calls-vs-one-no-destructuring/1 which is the same as the above-linked testcase but doesn't do destructuring of an array into an arglist and the collapsing of an arglist into an array for every call.  In that one the two-call version is in fact faster.

That is, the cost of allocating and filling the two-element return value array is much smaller than the cost of allocating and filling the 20-element array.  Since the two-call testcase in https://jsperf.com/two-calls-vs-one-returning-array does the latter twice, it ends up slower than the version that only does it once.

I was just sticking to how `Math.min` and `Math.max` work (e.g., they use discrete arguments). A better test probably would have passed them those args discretely rather than as ...nums.

Interestingly, V8 still does the minmax faster than the separate calls to min and max in your test, rating the two calls version 21% slower than the minmax. As you noted, SpiderMonkey runs the minmax much slower than the two calls (61%).

This is all a bit by-the-bye, performance is unlikely to be a big deal for minmax in the typical case, and when it is in a specific situation, a tailored solution to that specific situation would probably be best. The number of numbers being tested would have to be very large for two native-code loops to be the bottleneck in the code. I'd just drop the performance motivation from the proposal.

-- T.J. Crowder

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Re: Math.minmax

Xavier Stouder
In reply to this post by Xavier Stouder

I just removed performance from goals of the proposal, given how it seems to depend about how min and max are called.

 

Thanks for feedbacks.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Re: Math.minmax

Isiah Meadows-2
I'm honestly not convinced how this is actually useful. And also, just
based on the name, I'd expect it to be something closer to `[min, max]
= Math.minMax(foo, bar)`, which could effectively compile down for
integers to up to two register `mov`s followed by a single `cmpxchggt`
(compare and exchange if greater than).

Not that engines couldn't similarly reduce this equivalent, but
engines are usually way dumber than they could be with some of the
more complex reductions:

```js
// This should compile to the same thing assuming `foo` and
// `bar` are both integers, but no engine AFAIK does this.
var min = foo, max = bar;
if (min > max) { var tmp = max; max = min; min = tmp }

// This should also compile similarly, provided `foo` and `bar`
// are both integers and constant reference reads.
var min = Math.min(foo, bar)
var max = Math.max(foo, bar)
```
-----

Isiah Meadows
[hidden email]

Looking for web consulting? Or a new website?
Send me an email and we can get started.
www.isiahmeadows.com


On Fri, Jun 30, 2017 at 7:47 AM, Xavier Stouder <[hidden email]> wrote:

> I just removed performance from goals of the proposal, given how it seems to
> depend about how min and max are called.
>
>
>
> Thanks for feedbacks.
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Re: Math.minmax

Xavier Stouder
In reply to this post by Xavier Stouder

Even if I think it should be a performance improvement, the main goal actually is to improve readability and conciseness of the code.

 

When you say “I'd expect it to be something closer to [min, max] = Math.minMax(foo, bar)”, are you saying that minmax (or minMax) should only take two arguments ? I think that if it’s implemented like this, it would obviously be not so usefull.

 

Some questions about the proposal process :

-          Are champions reading and commenting this feed ? Can we have a comment on this proposal maybe ?

-          Is the purpose of proposals to question how the proposal would be implemented by JS engines ?

-          Talking about tests previously quoted : Is an JS implementation of this proposal just approaching how efficient (or not) would be the proposal after being implemented by JS engines ?

 

Thanks for your feedback.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Re: Math.minmax

Jordan Harband
To me it seems like minmax is *less* readable - between repeating the RHS (with min and max) vs condensing them and having nonobvious LHS syntax (with minmax), I'd prefer the current situation.

On Tue, Jul 4, 2017 at 8:37 AM, Xavier Stouder <[hidden email]> wrote:

Even if I think it should be a performance improvement, the main goal actually is to improve readability and conciseness of the code.

 

When you say “I'd expect it to be something closer to [min, max] = Math.minMax(foo, bar)”, are you saying that minmax (or minMax) should only take two arguments ? I think that if it’s implemented like this, it would obviously be not so usefull.

 

Some questions about the proposal process :

-          Are champions reading and commenting this feed ? Can we have a comment on this proposal maybe ?

-          Is the purpose of proposals to question how the proposal would be implemented by JS engines ?

-          Talking about tests previously quoted : Is an JS implementation of this proposal just approaching how efficient (or not) would be the proposal after being implemented by JS engines ?

 

Thanks for your feedback.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Re: Math.minmax

Xavier Stouder
In reply to this post by Xavier Stouder

It’s more concise and if you’re comfortable with destructuring assignment syntax, I think it’s also more readable.

 

Whatever, differents folks, differents strokes. This proposal offer the possibility to reduce by two the length of a “get min and max” operation, and probably improve the performance of the operation when used with large amounts of numbers.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Re: Math.minmax

Jordan Harband
To have that be worth a language change, I think you'd have to make a compelling argument that the performance of Math.min and Math.max, used together on the same large set of numbers, was sufficiently slow as to make widely used use cases untenable without your proposal.

I'd be happy to review the results of that research.

On Tue, Jul 4, 2017 at 12:24 PM, Xavier Stouder <[hidden email]> wrote:

It’s more concise and if you’re comfortable with destructuring assignment syntax, I think it’s also more readable.

 

Whatever, differents folks, differents strokes. This proposal offer the possibility to reduce by two the length of a “get min and max” operation, and probably improve the performance of the operation when used with large amounts of numbers.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Re: Math.minmax

Xavier Stouder
In reply to this post by Xavier Stouder

You can run three tests here : https://esbench.com/bench/595c1b1899634800a03488b9

Running minMax polyfill and min max with two instructions on 2, 1000 or 100000 numbers.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Re: Math.minmax

Jordan Harband
Thanks, that's helpful.

The results I get range from a 2x improvement for 2 numbers, to a 3x improvement for 1000 numbers (both 100K number examples get me a RangeError in Safari).

What concrete use cases are possible with the performance of minmax that aren't possible with a separate min and max?

On Tue, Jul 4, 2017 at 4:13 PM, Xavier Stouder <[hidden email]> wrote:

You can run three tests here : https://esbench.com/bench/595c1b1899634800a03488b9

Running minMax polyfill and min max with two instructions on 2, 1000 or 100000 numbers.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Re: Math.minmax

Xavier Stouder
In reply to this post by Xavier Stouder

The result is not so obvious on V8 (x0.9 on 2 numbers and x2 improvement for 1000 and 100000 numbers).

 

It would be helpful, for example, in the case of system monitoring. A friend of mine receives raw datas and he regularly needs to get min and max to handle those datas.

He could do that with both min and max, but he clearly told me that when he’s working with one year of QoS datas, x2 improvement can’t be ignored.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Math.minmax

Boris Zbarsky
In reply to this post by Jordan Harband
On 7/4/17 9:34 PM, Jordan Harband wrote:
> The results I get range from a 2x improvement for 2 numbers, to a 3x
> improvement for 1000 numbers

Again, did you test without the array destructuring and recreation bits?
  I expect those dominate here, just like in the jsbench benchmarks
posted before.

-Boris
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Re: Math.minmax

Xavier Stouder
In reply to this post by Xavier Stouder

Sorry for the delay!

I just added some benchmarks, please tell me what you think about them!


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Loading...