Skip to content

Commit

Permalink
timers: improve Timer.now() performance
Browse files Browse the repository at this point in the history
Record the start time so we can make the return value of Timer.now()
relative to it, increasing the chances that it fits in a tagged integer
instead of a heap-allocated double, at least for the first one or two
billion milliseconds.

PR-URL: #2256
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
  • Loading branch information
bnoordhuis committed Jul 27, 2015
1 parent 3663b12 commit 543dabb
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ inline Environment::Environment(v8::Local<v8::Context> context,
uv_loop_t* loop)
: isolate_(context->GetIsolate()),
isolate_data_(IsolateData::GetOrCreate(context->GetIsolate(), loop)),
timer_base_(uv_now(loop)),
using_smalloc_alloc_cb_(false),
using_domains_(false),
using_abort_on_uncaught_exc_(false),
Expand Down Expand Up @@ -286,6 +287,10 @@ inline Environment::TickInfo* Environment::tick_info() {
return &tick_info_;
}

inline uint64_t Environment::timer_base() const {
return timer_base_;
}

inline bool Environment::using_smalloc_alloc_cb() const {
return using_smalloc_alloc_cb_;
}
Expand Down
2 changes: 2 additions & 0 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ class Environment {
inline AsyncHooks* async_hooks();
inline DomainFlag* domain_flag();
inline TickInfo* tick_info();
inline uint64_t timer_base() const;

static inline Environment* from_cares_timer_handle(uv_timer_t* handle);
inline uv_timer_t* cares_timer_handle();
Expand Down Expand Up @@ -501,6 +502,7 @@ class Environment {
AsyncHooks async_hooks_;
DomainFlag domain_flag_;
TickInfo tick_info_;
const uint64_t timer_base_;
uv_timer_t cares_timer_handle_;
ares_channel cares_channel_;
ares_task_list cares_task_list_;
Expand Down
2 changes: 2 additions & 0 deletions src/timer_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ class TimerWrap : public HandleWrap {
Environment* env = Environment::GetCurrent(args);
uv_update_time(env->event_loop());
uint64_t now = uv_now(env->event_loop());
CHECK(now >= env->timer_base());
now -= env->timer_base();
if (now <= 0xfffffff)
args.GetReturnValue().Set(static_cast<uint32_t>(now));
else
Expand Down
8 changes: 8 additions & 0 deletions test/parallel/test-timers-now.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';

const common = require('../common');
const assert = require('assert');

// Return value of Timer.now() should easily fit in a SMI right after start-up.
const Timer = process.binding('timer_wrap').Timer;
assert(Timer.now() < 0x3ffffff);

0 comments on commit 543dabb

Please sign in to comment.