Date.now & new Date performance

42 views
Skip to first unread message

Paweł Badeński

unread,
Jun 5, 2020, 2:57:07 PM6/5/20
to v8-users
Hi,

Wondering if someone can help with a bit of context to satisfy mu curiosity! :D

We are using Date.now & new Date quite a bit in our application (financial domain). I run a few micro-benchmarks and was wondering why do these report being relatively slow (as compared to construction of other objects). In fact all Date methods seem rather slow. Am I having wrong expectations for these to be faster? Are they as fast as they could be, or is it that Date just never got enough love in terms of performance optimizations? Really curious to get more color on this!

Benchmarks:

Date.now() x 9,454,436 ops/sec ±1.09% (65 runs sampled)

new Date() x 5,594,688 ops/sec ±1.87% (64 runs sampled)

[1, 2, 3] x 124,719,052 ops/sec ±0.90% (64 runs sampled)

{ a: 1, b: 2, c: 3 } x 112,368,878 ops/sec ±0.83% (65 runs sampled)

new Object({ a: 1, b: 2, c: 3 }) x 32,547,566 ops/sec ±0.64% (64 runs sampled)



Thanks!
Pawel

Al Mo

unread,
Jun 5, 2020, 3:02:22 PM6/5/20
to v8-u...@googlegroups.com
[Warning. mere speculation]

Perhaps it has to do with having to make a system call to get the current time.

Alex.

--
--
v8-users mailing list
v8-u...@googlegroups.com
http://groups.google.com/group/v8-users
---
You received this message because you are subscribed to the Google Groups "v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/v8-users/6d98a6eb-4961-42f3-9b7c-7c309b30ea17o%40googlegroups.com.

Jakob Kummerow

unread,
Jun 5, 2020, 3:14:02 PM6/5/20
to v8-users
Yes, getting the current time from the operating system is significantly slower than allocating a simple JS object like [1, 2, 3]. That's not going to change.

As you can see, Date.now() is significantly faster than new Date(), so that's preferable when performance/overhead matters. Other than that, I'd simply recommend not to call either function overly often -- they have millisecond resolution, so calling them very frequently just means that you'll get the same values back repeatedly.

In particular, I've seen folks try to get profiling data by calling Date.now() before and after each function call. For small functions, that's not a good idea, because you'll mostly be measuring the overhead of the Date.now() calls themselves. When you need to profile, use a profiler. (I've seen microbenchmarks where profiling revealed that half the time was spent in Date.now() calls!)

If you want to perform some cheap action repeatedly before a timer runs out, it can help to have a double loop, e.g.:
while (Date.now() < deadline) {
  // Try a bunch of times, not just once.
  for (let i = 0; i < 1000; i++) {
    very_quick_thing();
  }
}
Tune the 1000 in the example until you see that the for-loop takes about a millisecond to finish (if it's accurate to an order of magnitude, i.e. between 0.1 and 10ms, that's good enough, and gives you some robustness towards hardware differences).


Paweł Badeński

unread,
Jun 8, 2020, 5:38:07 AM6/8/20
to v8-users
That's all fair enough. Shouldn't then constructing via some constructors be faster - where it doesn't require operating system call? Because I'm still seeing rather slow calls..

new Date(1591386221897) x 9,329,719 ops/sec ±2.66% (64 runs sampled)

new Date(2019, 1, 1, 12, 0, 1, 1) x 2,636,300 ops/sec ±0.83% (65 runs sampled)

Date.UTC(2019, 1, 1, 12, 0, 1, 1) x 11,741,842 ops/sec ±0.79% (65 runs sampled)


Source: https://stackblitz.com/edit/js-dvq8ri


On Friday, 5 June 2020 20:14:02 UTC+1, Jakob Kummerow wrote:
Yes, getting the current time from the operating system is significantly slower than allocating a simple JS object like [1, 2, 3]. That's not going to change.

As you can see, Date.now() is significantly faster than new Date(), so that's preferable when performance/overhead matters. Other than that, I'd simply recommend not to call either function overly often -- they have millisecond resolution, so calling them very frequently just means that you'll get the same values back repeatedly.

In particular, I've seen folks try to get profiling data by calling Date.now() before and after each function call. For small functions, that's not a good idea, because you'll mostly be measuring the overhead of the Date.now() calls themselves. When you need to profile, use a profiler. (I've seen microbenchmarks where profiling revealed that half the time was spent in Date.now() calls!)

If you want to perform some cheap action repeatedly before a timer runs out, it can help to have a double loop, e.g.:
while (Date.now() < deadline) {
  // Try a bunch of times, not just once.
  for (let i = 0; i < 1000; i++) {
    very_quick_thing();
  }
}
Tune the 1000 in the example until you see that the for-loop takes about a millisecond to finish (if it's accurate to an order of magnitude, i.e. between 0.1 and 10ms, that's good enough, and gives you some robustness towards hardware differences).


On Fri, Jun 5, 2020 at 9:02 PM Al Mo <almo...@gmail.com> wrote:
[Warning. mere speculation]

Perhaps it has to do with having to make a system call to get the current time.

Alex.

On Fri, Jun 5, 2020 at 1:57 PM Paweł Badeński <pawel....@gmail.com> wrote:
Hi,

Wondering if someone can help with a bit of context to satisfy mu curiosity! :D

We are using Date.now & new Date quite a bit in our application (financial domain). I run a few micro-benchmarks and was wondering why do these report being relatively slow (as compared to construction of other objects). In fact all Date methods seem rather slow. Am I having wrong expectations for these to be faster? Are they as fast as they could be, or is it that Date just never got enough love in terms of performance optimizations? Really curious to get more color on this!

Benchmarks:

Date.now() x 9,454,436 ops/sec ±1.09% (65 runs sampled)

new Date() x 5,594,688 ops/sec ±1.87% (64 runs sampled)

[1, 2, 3] x 124,719,052 ops/sec ±0.90% (64 runs sampled)

{ a: 1, b: 2, c: 3 } x 112,368,878 ops/sec ±0.83% (65 runs sampled)

new Object({ a: 1, b: 2, c: 3 }) x 32,547,566 ops/sec ±0.64% (64 runs sampled)



Thanks!
Pawel

--
--
v8-users mailing list
v8-u...@googlegroups.com
http://groups.google.com/group/v8-users
---
You received this message because you are subscribed to the Google Groups "v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to v8-u...@googlegroups.com.

--
--
v8-users mailing list
v8-u...@googlegroups.com
http://groups.google.com/group/v8-users
---
You received this message because you are subscribed to the Google Groups "v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to v8-u...@googlegroups.com.

Jakob Kummerow

unread,
Jun 8, 2020, 11:18:10 AM6/8/20
to v8-users
Due to how complicated the Date constructor is, it is expected to be much slower than allocating an object. Beyond the sheer amount of stuff it has to do per spec, this is amplified by the fact that the more complicated (and the less frequently performed) an operation is, the more likely engines are to implement it in a slower (but more manageable) fashion. Specifically, object allocation has all sorts of fast paths like inlining in optimized code, which new Date(...) doesn't have.

Paweł Badeński

unread,
Jun 9, 2020, 5:19:17 AM6/9/20
to v8-users
Thanks for the context! To that point - do you know if optimising Date has ever been a topic of conversation? I'm curious if it's just impossible/very hard or just never been a priority.

On Monday, 8 June 2020 16:18:10 UTC+1, Jakob Kummerow wrote:
Due to how complicated the Date constructor is, it is expected to be much slower than allocating an object. Beyond the sheer amount of stuff it has to do per spec, this is amplified by the fact that the more complicated (and the less frequently performed) an operation is, the more likely engines are to implement it in a slower (but more manageable) fashion. Specifically, object allocation has all sorts of fast paths like inlining in optimized code, which new Date(...) doesn't have.


Jakob Kummerow

unread,
Jun 9, 2020, 5:53:53 AM6/9/20
to v8-users
Probably both: we don't see the Date constructor much when profiling things, and we don't expect that a whole lot could be gained when trying to make it faster, so the effort-to-benefit ratio is probably just not worth it.

Out of my curiosity: what problem are you solving by "using Date.now & new Date quite a bit"?


--
--
v8-users mailing list
v8-u...@googlegroups.com
http://groups.google.com/group/v8-users
---
You received this message because you are subscribed to the Google Groups "v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/v8-users/5937ddba-e8f2-40c7-90f9-99f09578ccf9o%40googlegroups.com.

Paweł Badeński

unread,
Jun 9, 2020, 6:59:01 AM6/9/20
to v8-users
I was a bit imprecise when posting that... It's actually the "new Date" that we use a lot and is in fact consistently showing in CPU profiling (together with other Date methods). We use it for financial algorithms - specifically financial derivatives. There's quite a lot of Date logic involved with this type of stuff. 


On Tuesday, 9 June 2020 10:53:53 UTC+1, Jakob Kummerow wrote:
Probably both: we don't see the Date constructor much when profiling things, and we don't expect that a whole lot could be gained when trying to make it faster, so the effort-to-benefit ratio is probably just not worth it.

Out of my curiosity: what problem are you solving by "using Date.now & new Date quite a bit"?


To unsubscribe from this group and stop receiving emails from it, send an email to v8-u...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages