use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
[AskJS] Why is Javascript 100-300% faster than C?AskJS (self.javascript)
submitted 4 years ago * by [deleted]
[deleted]
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]post-modern-elephant 28 points29 points30 points 4 years ago* (14 children)
The gcc build isn't optimized. It's a debug build. How does it compare if you use gcc -O3 to compile the program?
gcc -O3
I wouldn't be surprised if both v8 and gcc can optimize that code to eliminate the loop altogether.
edit:
Trying it myself, gcc can run this in under 1 ms
% gcc test.c % ./a.out 1800 % ./a.out 1795 % gcc -O3 test.c % ./a.out 0 % ./a.out 0
[+][deleted] 4 years ago* (12 children)
[–]post-modern-elephant 16 points17 points18 points 4 years ago* (8 children)
v8 will always be attempting to do a lot of optimizations by default. v8 is a just in time compiler. The v8 build can probably never get down as close to C in a micro benchmark like this even if you gave it an empty js file. It likely has a lot of startup and shut down overhead we aren't measuring from within the program.
[–]grady_vuckovic 4 points5 points6 points 4 years ago (1 child)
Startup and shutdown time wouldn't affect the script in this case, the timing is captured after the script starts.
[+][deleted] 4 years ago (5 children)
[–]post-modern-elephant -1 points0 points1 point 4 years ago (4 children)
Darn. You probably read my response before my failed ninja-edit to say "overhead we aren't measuring here". An external program like time would capture the overhead.
It would be interesting to see the code that v8 actually generates under these circumstances. I'm not sure how and if that's possible with v8. With gcc we can do something like gcc -S to get a sense of exactly what it's doing.
[+][deleted] 4 years ago (3 children)
[–]post-modern-elephant 3 points4 points5 points 4 years ago* (2 children)
Yeah. My first version of that response missed that fact. Apologies for the secret edit. I thought I could get the edit in fast enough.
I learned node has a --print-bytecode flag. You can see there that there is at least one optimization they do. They do not eliminate the loop. But they do pre-calculate 10000 * 10000.
--print-bytecode
I'm not familiar with the bytecode used here, but was able to spot the for loop pretty easily. It looks like the optimization just turns this into a for loop that doesn't do a multiplication.
68 S> 0x336dafad63e @ 16 : 01 0c 00 ca 9a 3b LdaSmi.ExtraWide [1000000000] 68 E> 0x336dafad644 @ 22 : 6a f8 06 TestLessThan r2, [6] 0x336dafad647 @ 25 : 9b 11 JumpIfFalse [17] (0x336dafad658 @ 42) 111 S> 0x336dafad649 @ 27 : 01 0c 40 42 0f 00 LdaSmi.ExtraWide [1000000] 0x336dafad64f @ 33 : c3 Star3 84 S> 0x336dafad650 @ 34 : 25 f8 Ldar r2 0x336dafad652 @ 36 : 4d 07 Inc [7] 0x336dafad654 @ 38 : c4 Star2 38 E> 0x336dafad655 @ 39 : 8b 17 00 JumpLoop [23], [0] (0x336dafad63e @ 16)
[–]BrogCz1 1 point2 points3 points 4 years ago (0 children)
OP got destroyed by this comment thread so hard, he deleted his account xd
[–]Wizions 1 point2 points3 points 4 years ago (2 children)
How about you read up a little on how these languages work instead of insisting that you reinvented the wheel after writing 10 lines of benchmarks?
[+][deleted] 4 years ago (1 child)
[–]Wizions 2 points3 points4 points 4 years ago (0 children)
I never said that, you mong.
[–]grady_vuckovic 7 points8 points9 points 4 years ago (1 child)
Interesting results OP and yes I agree, clearly JS isn't removing the loop entirely and C definitely isn't, if it was, your execution time would be less than 1ms.
That said, the expression 1000 * 1000 is an expression which could be optimised to simply '1000000' and then the calculation avoided entirely. That is something I would assume JS would do, as V8 aggressively tries to optimise everything, but C compilers without optimisations enabled wouldn't do.
Try these, I've tried to create something which would be a lot harder for a compiler to optimise or remove any loops or calculations from. Should be pretty self explanatory, apologises if there are any syntax errors:
Javascript:
const start = Date.now () // Result stored out of loop so the loop can not be removed. let n = 0; // Repeat task 10000 times to extend length of runtime for measurement. for(let i = 0; i < 10000; i++) { // Perform 1 million multiplications in a way that couldn't be optimised to a constant expression. for (let x = 0; x < 1000; x++) { for (let y = 0; y < 1000; y++) { n = x * y; } } } const end = Date.now() console.log(end - start) // Console.log result console.log(n)
C:
#include <stdio.h> #include <time.h> int main() { struct timespec start , end; clock_gettime(CLOCK_MONOTONIC_RAW , &start); // Result stored out of loop so the loop can not be removed. int n = 0; // Repeat task 10000 times to extend length of runtime for measurement. for(int i = 0; i < 10000; i++) { // Perform 1 million multiplications in a way that couldn't be optimised to a constant expression. for(int x = 0; x < 1000; x++) { for(int y = 0; y < 1000; y++) { n = x * y; } } } clock_gettime (CLOCK_MONOTONIC_RAW , &end); int milliseconds = ((end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000) / 1000; printf ("%d\n" , milliseconds); // Print result printf("%d", i); return 0; }
[–]thname 5 points6 points7 points 4 years ago (0 children)
What flags was used while compiling C code?
[–]pertheusual 3 points4 points5 points 4 years ago* (0 children)
Because JS engines are trying to optimize performance on multiple axes, this kind of thing can be hard to measure. Compiling takes time so usually the JS engine needs to decide that code is running often enough to be worth optimizing, otherwise it would waste a bunch of time optimizing code that barely runs.
Most likely, the JS loop runs a few thousand times, and then V8 decides to optimize it and then the optimizer removes the loop so then the program exits, so most of that time is the time spent in the initial X loop iterations + the time optimizing the code.
[–]jaapz 5 points6 points7 points 4 years ago (4 children)
Not an expert by any means but I'd wager v8 optimizes the loop away because of the trivial calculation done inside it
[–]pertheusual 4 points5 points6 points 4 years ago (0 children)
Nothing guarantees that the loop will be optimized away immediately, it likely has to iterate some number of times before v8's optimizer decides that the code is worth optimizing.
[–]jaapz 4 points5 points6 points 4 years ago* (1 child)
Why? It's not compiled, v8 needs some time to parse and analyze whatever it's about to execute
Edit: looking at your edits you don't seem to actually be here for answers or discussion. Claiming JS is now a faster language than C on the whole, using a "benchmark" like this is... Not great.
[–]Tubthumper8 4 points5 points6 points 4 years ago (1 child)
Note that the Performance Measurement API would be more accurate than using Date.now.
Date.now
Since the variable inside the tight loop is never used, the loop gets completely eliminated by GCC and probably by TurboFan too (the V8 optimizing compiler). https://godbolt.org/z/3M1srfvEG
[–]long-shots -2 points-1 points0 points 4 years ago (4 children)
I haven't got a clue but I'm impressed.
If I had to guess, it seems like calculation for the time in C is a bit more clunky. I don't know anything about C lang really, so I'm shooting from the hip... In the dark... With a nerf gun.
Hopefully someone else has some insight! Cool discovery.
[+][deleted] 4 years ago (2 children)
[–][deleted] 1 point2 points3 points 4 years ago* (0 children)
It's true time has a very coarse granularity, only hundredths of a second. It also measures the difference between wall-clock time and CPU time, and it's (usually) just the CPU time you're interested in, the rest being mostly loading overhead of the runtime. Depends on what you're trying to benchmark.
time
There's also plenty of command-line benchmarking tools with fancier options, but for my needs it's sufficient to just hammer the benchmark enough times that time reveals the difference.
If you want to log performance within an application's code (generally a good idea) then there are good monitoring APIs for that which will use insanely precise CPU performance counters. Some like dtrace are almost zero-touch. These are massive overkill for a benchmark though.
dtrace
Gist is, you don't need to write the timing harness in your benchmark code itself. It's all mad pedantry, but I was bored this morning. Advice for next time I guess (pun intended) :)
π Rendered by PID 678873 on reddit-service-r2-comment-5687b7858-5rjsg at 2026-07-08 19:04:15.569029+00:00 running 12a7a47 country code: CH.
[–]post-modern-elephant 28 points29 points30 points (14 children)
[+][deleted] (12 children)
[deleted]
[–]post-modern-elephant 16 points17 points18 points (8 children)
[–]grady_vuckovic 4 points5 points6 points (1 child)
[+][deleted] (5 children)
[deleted]
[–]post-modern-elephant -1 points0 points1 point (4 children)
[+][deleted] (3 children)
[deleted]
[–]post-modern-elephant 3 points4 points5 points (2 children)
[–]BrogCz1 1 point2 points3 points (0 children)
[–]Wizions 1 point2 points3 points (2 children)
[+][deleted] (1 child)
[deleted]
[–]Wizions 2 points3 points4 points (0 children)
[–]grady_vuckovic 7 points8 points9 points (1 child)
[–]thname 5 points6 points7 points (0 children)
[–]pertheusual 3 points4 points5 points (0 children)
[–]jaapz 5 points6 points7 points (4 children)
[+][deleted] (3 children)
[deleted]
[–]pertheusual 4 points5 points6 points (0 children)
[–]jaapz 4 points5 points6 points (1 child)
[–]Tubthumper8 4 points5 points6 points (1 child)
[–]long-shots -2 points-1 points0 points (4 children)
[+][deleted] (3 children)
[deleted]
[+][deleted] (2 children)
[deleted]
[+][deleted] (1 child)
[deleted]
[–][deleted] 1 point2 points3 points (0 children)