Using const to remove debug code? Is there something stopping implementers from doing this?
Lately I've been writing very processor heavy Javascript. I feel like it could benefit a lot from having a syntax feature for removing debug statements. Obviously JS is interpreted and not compiled, so I'm not sure if this sounds completely unrealistic, but it has some very useful scenarios. I like to write verbose type checking for functions to check ranges and throw exceptions if invalid input is detected. The issue is in a production environment (especially with games) the code executes too slowly with all the extra branches. It would be nice if there was a simple syntax to treat code as if it's commented out when a flag is set. In some languages this is done with preprocessor statements like: #if debug console.log(Debug Mode); #else console.log(Release Mode); #endif The alternative is simply: const debug = false; if (debug) { // Tons of type checking } What I'd expect would be possible for an implementer is to get to the constant and evaluate the branch and remove the whole statement before running it through the JIT. This would allow a very standard way to turn on and off pieces of code. An example program: // Debug Off Control { console.time(benchmark control); for (var i = 0; i 1000; ++i) { } console.timeEnd(benchmark control); } // Debug Off { const debugOff = false; var debugOffCounter = 0; console.time(benchmark debug off); for (var i = 0; i 1000; ++i) { if (debugOff) { debugOffCounter++; } } console.timeEnd(benchmark debug off); } // Debug On { const debugOn = true; var debugOnCounter = 0; console.time(benchmark debug on); for (var i = 0; i 1000; ++i) { if (debugOn) { debugOnCounter++; } } console.timeEnd(benchmark debug on); } http://jsfiddle.net/9LCra/ On the latest Firefox there's a 11 ms difference between the control and using a constant in the if. In chrome there's a 23 ms difference. Is there anything stopping an implementer from evaluating the constant and making the control and debug off identical in performance? I kind of want this to be like a standard goto technique that's expected to work since I believe right now the alternative is to simply create two files or remove anything that might slow things down. I decided to post here first in case there's a fundamental reason that such a use case would be impossible or if an alternative was in the works that would fit this goal. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Using const to remove debug code? Is there something stopping implementers from doing this?
Le 28/11/2013 09:59, Brandon Andrews a écrit : Lately I've been writing very processor heavy Javascript. I feel like it could benefit a lot from having a syntax feature for removing debug statements. Obviously JS is interpreted and not compiled, so I'm not sure if this sounds completely unrealistic, but it has some very useful scenarios. I like to write verbose type checking for functions to check ranges and throw exceptions if invalid input is detected. The issue is in a production environment (especially with games) the code executes too slowly with all the extra branches. It would be nice if there was a simple syntax to treat code as if it's commented out when a flag is set. Does this need to be part of JavaScript (and be implemented in web browsers)? From what I understand, what you're describing is purely a development time concern and not a (production) runtime concern, so I feel the solution should be found in better development tooling. Good news! Olov Lassus already worked on something like this! http://blog.lassus.se/2011/03/c-style-assertions-in-javascript-via.html https://www.youtube.com/watch?v=yk6t4kRN53w I haven't looked at it too much, but it might be possible to do assertions (that run in dev, but not in prod) with Sweet.js [1] macros. Potentially that's something that could be part of TypeScript too (I haven't seen an issue on this topic or in the roadmap, but maybe that's an addition they'd be open to do?). JavaScript isn't compiled, but we can build tools that do compile to JS without requiring support from the browser. David [1] http://sweetjs.org/ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Using const to remove debug code? Is there something stopping implementers from doing this?
Both Closure Compiler and UglifyJS has something called defines which allow you to override the value of a variable using a command line parameter. Combining this with their dead code removal and you have a preprocessor tool similar to #ifdefs. https://github.com/mishoo/UglifyJS2#conditional-compilation https://developers.google.com/closure/compiler/docs/js-for-compiler (search for @define) On Nov 28, 2013 5:25 AM, David Bruant bruan...@gmail.com wrote: Le 28/11/2013 09:59, Brandon Andrews a écrit : Lately I've been writing very processor heavy Javascript. I feel like it could benefit a lot from having a syntax feature for removing debug statements. Obviously JS is interpreted and not compiled, so I'm not sure if this sounds completely unrealistic, but it has some very useful scenarios. I like to write verbose type checking for functions to check ranges and throw exceptions if invalid input is detected. The issue is in a production environment (especially with games) the code executes too slowly with all the extra branches. It would be nice if there was a simple syntax to treat code as if it's commented out when a flag is set. Does this need to be part of JavaScript (and be implemented in web browsers)? From what I understand, what you're describing is purely a development time concern and not a (production) runtime concern, so I feel the solution should be found in better development tooling. Good news! Olov Lassus already worked on something like this! http://blog.lassus.se/2011/03/c-style-assertions-in-javascript-via.html https://www.youtube.com/watch?v=yk6t4kRN53w I haven't looked at it too much, but it might be possible to do assertions (that run in dev, but not in prod) with Sweet.js [1] macros. Potentially that's something that could be part of TypeScript too (I haven't seen an issue on this topic or in the roadmap, but maybe that's an addition they'd be open to do?). JavaScript isn't compiled, but we can build tools that do compile to JS without requiring support from the browser. David [1] http://sweetjs.org/ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Using const to remove debug code? Is there something stopping implementers from doing this?
On Nov 28, 2013, at 12:59 AM, Brandon Andrews warcraftthre...@sbcglobal.net wrote: Lately I've been writing very processor heavy Javascript. I feel like it could benefit a lot from having a syntax feature for removing debug statements. Obviously JS is interpreted and not compiled, so I'm not sure if this sounds completely unrealistic, but it has some very useful scenarios. I like to write verbose type checking for functions to check ranges and throw exceptions if invalid input is detected. The issue is in a production environment (especially with games) the code executes too slowly with all the extra branches. It would be nice if there was a simple syntax to treat code as if it's commented out when a flag is set. In some languages this is done with preprocessor statements like: #if debug console.log(Debug Mode); #else console.log(Release Mode); #endif The alternative is simply: const debug = false; if (debug) { // Tons of type checking } This falls firmly within the realm of things that a JS engine should be able to infer automatically and so using const isn't useful from a performance standpoint. You will get the same effect from var debug = false. This will probably already get optimized the way you want by optimizing JITs. If it isn't then you should file bugs against those JITs. No need to change the language. Here's why var is good enough provided that you do the var debug = false thing at the top of the function: - it's obvious that the variable is only assigned once and that it's assigned before any use. - var is one of the few JS constructs that lends itself naturally to static reasoning, unless you use eval or with. What this means is that every use of debug can be folded to its One True Value (I.e. false in this case) unless you use it from within a with or you have an eval statement in the same scope (how well a JS engine handles eval statements varies greatly so don't use eval if you want performance). All of the examples you give will work properly if you say var instead of const. Here's an example of eval being a hater: function foo() { var debug = false; eval(blah); // did this change debug or not? It's fair to assume that a JS engine will conservatively assume that debug gets changed by this. if (debug) console.log(things); } So, I guess we could concede that const would be useful if you had such evals, but then again, if you have such evals then an if (debug) statement not getting folded is the least of your performance worries. Eval is kinda slow. ;-) Now, some insight into why you might currently be seeing a performance difference with or without the if (debug) statements: - if you're defining debug in an outer function and using it in a nested function. Even though that's easy to optimize some engines may fail to do it. File bugs against those engines. - if an engine is seeing that blob of dead code and allowing it to affect inlining heuristics. This is a classic inlined bug; heck even C compiler people still have to fix performance bugs due to stuff like this. Again, file bugs against engines. If you can come up with an example program that runs faster without an if (debug) than with it, then file a bug against the relevant engines with that program attached. What I'd expect would be possible for an implementer is to get to the constant and evaluate the branch and remove the whole statement before running it through the JIT. This would allow a very standard way to turn on and off pieces of code. An example program: // Debug Off Control { console.time(benchmark control); for (var i = 0; i 1000; ++i) { } console.timeEnd(benchmark control); } // Debug Off { const debugOff = false; var debugOffCounter = 0; console.time(benchmark debug off); for (var i = 0; i 1000; ++i) { if (debugOff) { debugOffCounter++; } } console.timeEnd(benchmark debug off); } // Debug On { const debugOn = true; var debugOnCounter = 0; console.time(benchmark debug on); for (var i = 0; i 1000; ++i) { if (debugOn) { debugOnCounter++; } } console.timeEnd(benchmark debug on); } http://jsfiddle.net/9LCra/ On the latest Firefox there's a 11 ms difference between the control and using a constant in the if. In chrome there's a 23 ms difference. Is there anything stopping an implementer from evaluating the constant and making the control and debug off identical in performance? I kind of want this to be like a standard goto technique that's expected to work since I believe right now the alternative is to simply create two files or remove anything that might slow things down. I decided to post here first in case there's a fundamental reason that such a use case would be impossible or if an
Re: Using const to remove debug code? Is there something stopping implementers from doing this?
On 11/28/13 11:41 AM, Filip Pizlo wrote: Here's why var is good enough provided that you do the var debug = false thing at the top of the function: I would think it would be done at window scope, or in some module scope, not at the top of every function, no? -Boris ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Using const to remove debug code? Is there something stopping implementers from doing this?
On Nov 28, 2013, at 9:51 AM, Boris Zbarsky bzbar...@mit.edu wrote: On 11/28/13 11:41 AM, Filip Pizlo wrote: Here's why var is good enough provided that you do the var debug = false thing at the top of the function: I would think it would be done at window scope, or in some module scope, not at the top of every function, no? Yes. As I pointed out later in that mail, having such an implicit constant defined in an outer function and used in a nested function should be fine but some engines may not optimize it yet. And I suggested that if you find examples of this not working right you should file bugs against the engines. But it turns out that if it's done at global scope then constant-inferring the variable is even easier than if it was local, so that kind of idiom definitely shouldn't require language help. -Filip -Boris ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss