-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Conversation
I don't remember if node exposes it, but libev already has the "current time", which should be precise enough for that usage. No syscall is required since the value is already in user-space, and you can remove the cache mechanism. |
I looked for that, but couldn't find anything. If it were exposed, this would be my preference as well (although a cache may still be necessary; in my testing, formatting the date string on every request had a significant impact). |
In general I like the idea, but:
|
I'm really sure that if we can use ev_now() [1], the time lookup overhead will disappear, but it is not exposed to JavaScript. According to the doc [2] ev_tstamp is an alias for double, which is what v8::Date::New() accepts so it would be perfect. I tried looking for an existing module to host that new function, but to my eyes, none of them really match in terms of categorization. I will try to build a patch to provide process.now() so that we can test that out. [1] http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#GLOBAL_FUNCTIONS |
I just posted a broken patch that exposes ev_now(). Even if the date is not right, I would be curious to see what it changes in terms of performance. What methodology did you use to test the performances ? More specifically, what client did you use to test the request throughput ? |
i'm not sure ev_now() will be faster given the overhead of the c++ function call.. |
I benchmaked on two boxes (core i3 and corei5, on gigabit) at home using Siege, just doing a simple Hello World. Rough numbers (I'm not trusting siege yet):
The interesting thing for me was that caching just the Date object didn't really help; it took it to about 13,400 IIRC. It's the .toUTCString() that seems to be expensive, which is why a cache still might be necessary even if ev_now is exposed. I'll fix spacing and add a test. |
Hi mnot, can you re-do your benchmarks with the latest patch I posted to the list ? By caching the Date() object, I was able to improve the process.now() performances tenfold. Also, since the Date() object doesn't change, you could cache the computed utcDate on it and avoid the timeout mechanism. |
exports.utcDate = function () { gives 13900 req/sec. Whereas changing it to: gives 13600 req/sec. Not sure why it's slower. I ran each one a few times to warm up caches, etc. Caching the date string (generated by new Date()) as per the patch gives 14600 req/sec. Returning a static string "foo" from utcDate gives 14600 req/sec (all of these numbers should be taken with a big grain of salt, of course). I don't doubt that having the ev date available is useful and a perf win (e.g., for logging); it's just that here, since the string has a one-second resolution, caching the string itself gives benefits that dwarf the overhead of the date syscall. I also wonder if V8 is pulling some optimisations of its own. Given this test script: var f = new Date(); putting it through strace gives: open("/home/mnot/test.js", O_RDONLY) = 5 Note that there's only one clock_gettime call... |
Okay, nice to know that v8 is smart :) I tried reproducing the tests locally, but I didn't have two machines at hand, and the results are pretty much cpu-bound. I get around 6700 req/s with your patch and 6600 with my funky changes (with the new process.loopTime accessor), all the time with 100% CPU usage. In the end, I think that those micro-optimisations will be lost in the noise of the more-complicated programs. Maybe the only remaining thing that I would suggest, is moving sys.utcDate as a utility in the http module, since it's highly specify. |
As per RFC2616 section 14.18, Date headers are required in responses.
This patch adds them (except when already set), and caches the date string once per second to avoid the perf it of system calls and conversion to a string.
In my testing, the performance impact is negligible (i.e., lost in the noise; runs with and without it get around 14,000 req/sec for hello world, whereas generating the date each time results in an ~11% perf drop).
I haven't documented sys.utcDate (the date cache), as it's not clear it's useful elsewhere. Am happy to do so, or move it into http.js, if you think that's better.