Dear noders.
There's a hands-on demo I give every now and then, which shows why putting everything in try{}catch(e){} isn't a good idea. I usually give it to C# or Java developers that get a taste of node, and bring with them their old customs with them. It goes as follows.
Consider the following two files:
no-try.js
var i = 0;
function foo() {
if ( 0 == ++i % 100) console.log('depth - ', i);
foo();
}
foo()
with-try.js
var i = 0;
function foo() {
try {
if ( 0 == ++i % 100) console.log('depth - ', i);
foo();
} catch(e) {}
}
foo()
The test tries to find how many call-stack the code will enter before it crashes, and shows that the try-catch impacts significantly the call-stack depth.
I've been showing this demo ever since the ealy days of node. I did not get a class for a while, and now that I did - I started to show them the findings, but was so dismayed by the results - I had to open an issue about it and ask your opinion here.
Here are my results on this current workplace laptop, which is a dell M2800, i7vPro, 16G, bla bla.
|node -v | no-try|with-try|
+--------+-------+--------+
|v0.6.21 | 18400 | 11400 |
|v0.8.28 | 20900 | 11400 |
|v0.10.48| 20900 | 11400 |
|v0.12.18| 20700 | 11200 |
|v4.9.1 | 20600 | 17700 |
|v6.14.2 | 20600 | 17700 |
|v8.9.4 | 8200 | 7600 |
|v10.3.0 | 10800 | 9900 |
+--------+-------+--------+
Friends - I was dancing with joy when node 4.4 got to 20K depth, and was even happier when I saw you fond how to make these commonly abused try blocks was less significant.
But while you can still see the footprint of try blocks - in versions above 8 - the overall depth is much more limited...
Is that on purpose? Is there some inner mechanism that limits harder, or that these versions use so much more memory even with such a vanilla code?
@nodejs/v8
That's probably because of TurboFan and Ignition replacing the old execution pipeline in Node 8. I know for a fact that Ignition (the bytecode interpreter) uses more stack space. Not sure about TurboFan though and at which point the code even got optimized.
Can you run your code with --trace-opt to check when optimization happened? You can also run Node 8 and later with --no-opt to see how Turbofan's optimized code affects this. Pre Node 8 you can use --no-crankshaft to disable optimization, but the test with try-catch cannot be optimized by Crankshaft anyways.
@osher hey 馃憢
I see you work with Tikal and have an Israeli name (Welcome!). It doesn't really cross the language barrier well given how Hebrew works differently - we try to avoid gendered language here (Guys). People care about this here and we want to create a welcoming environment for everyone. Please consider editing this out of your post (People, Folks, etc works fine).
Node.js 8 changes the entire compiler toolchain as @hashseed explained :) Is there any actual real-life case where 10000 depth isn't sufficient in your code?
@osher https://github.com/davidmarkclements/v8-perf#the-trycatch-problem
@dnalborczyk - thanks for the reference - this is a great one.
I'm very ambivalent about the findings.
From one side - as a whole, reducing the differences between code styles is good. I'm gladly willing to yield my edge of selecting preferable code styles.
But on the other - the overall performance is degrading across the board - this hits me on my node.js pride...
I don't think this is actionable for us since it's a V8 issue so I'll go ahead and close this out.
edit: but thanks for the bug report, of course!