Created
March 23, 2010 07:28
-
-
Save zoka/340921 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <node.h> | |
#include <sys/time.h> | |
using namespace v8; | |
using namespace node; | |
Handle<Value> | |
seconds(const Arguments& args) | |
{ | |
timeval t1; | |
HandleScope scope; | |
gettimeofday(&t1, NULL); | |
return Number::New((double)t1.tv_sec + (double) t1.tv_usec / 1000000.0); | |
} | |
extern "C" void | |
init (Handle<Object> target) | |
{ | |
HandleScope scope; | |
Local<FunctionTemplate> _seconds = FunctionTemplate::New(seconds); | |
target->Set(String::New("seconds") , _seconds->GetFunction()); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
##include <stdio.h> | |
#include <unistd.h> | |
#include <sys/time.h> | |
// compile: g++ -o ttest ttest.cc | |
long long llong_time(timeval& t) { | |
return (long long)t.tv_sec * 1000000 + (long long) t.tv_usec; | |
} | |
long ulong_time(timeval& t) { | |
return (unsigned long )(t.tv_sec * 1000000 + t.tv_usec); | |
} | |
double double_time(timeval& t) { | |
return (double)t.tv_sec + (double) t.tv_usec / 1000000.0; | |
} | |
int main (void) { | |
unsigned long ul_now, ul_before; | |
long long ll_now, ll_before; | |
double d_now, d_before; | |
timeval now, before; | |
printf("Sleeping for one second ...\n"); | |
gettimeofday(&before, NULL); | |
usleep(1000000); | |
gettimeofday(&now, NULL); | |
printf("Sizeof unsigned long is %d\n", sizeof(unsigned long)); | |
printf("Sizeof long long is %d\n", sizeof(long long)); | |
printf("As unsigned long: before=%lu usec now=%lu usec ", | |
ul_before = ulong_time(before), | |
ul_now = ulong_time(now)); | |
printf("delta=%ld usec\n", ul_now - ul_before); | |
printf("As long long: before=%lld usec now=%lld usec ", | |
ll_before = llong_time(before), | |
ll_now = llong_time(now)); | |
printf("delta=%lld usec\n", ll_now - ll_before); | |
printf("As double: before=%f sec now=%f sec ", | |
d_before = double_time(before), | |
d_now = double_time(now)); | |
printf("delta=%f sec\n", d_now - d_before); | |
int i; | |
gettimeofday(&before, NULL); | |
ul_before = ulong_time(now); | |
for (i = 0; i < 1000000; i++); | |
ul_now = ulong_time(before); | |
gettimeofday(&now, NULL); | |
ul_now = ulong_time(now); | |
printf("ulong_time() overhead for 1000000 invocations =%ld usec\n", (ul_now - ul_before)); | |
gettimeofday(&before, NULL); | |
d_before = double_time(before); | |
for (i = 0; i < 1000000; i++); | |
d_now = double_time(now); | |
gettimeofday(&now, NULL); | |
d_now = double_time(now); | |
printf("double_time() overhead for 1000000 invocations=%f sec\n", (d_now - d_before)); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Here is output of above program on OS X: | |
$ ./ttest | |
Sleeping for one second ... | |
Sizeof unsigned long is 4 | |
Sizeof long long is 8 | |
As unsigned long: before=2061213856 usec now=2062213848 usec delta=999992 usec | |
As long long: before=1269328105939104 usec now=1269328106939096 usec delta=999992 usec | |
As double: before=1269328105.939104 sec now=1269328106.939096 sec delta=0.999992 sec | |
ulong_time() overhead for 1000000 invocations =2540 usec | |
double_time() overhead for 1000000 invocations=0.002471 sec | |
Conclusion: | |
Using unsigned long leads to multiplication overflow, | |
although the delta still seems to be correct for short intervals (less than ~ 4000 seconds). | |
Moreover, it is a just luck that C runtime multiplication overflow seems to preserve the difference. | |
This may not work on another platform. | |
Using llong_time() in Node is not possible since 64-bit integers are not supported as | |
JavaScript type. | |
Note that double_time() is slightly faster than ulong_time() which is quite amazing. | |
So, I think that just one floating point method that provides value in seconds should | |
be sufficient. | |
See bindings.cc above, note that original seconds() method had improper casting order, | |
which would lead to loss of precision. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment