简体   繁体   中英

Is there a performance difference between foo(123) and window[“foo”](123)?

I wonder if there's any performance difference when calling the function foo() between foo(123) and window["foo"](123) .

Well, 10 loops by 100 million operations gave this (chrome):

在此处输入图像描述

You can notice, that at the 2-nd line it makes some optimizations and starts running faster. Other differences can be neglected.

 for( let j = 0; j < 10; j++ ) { let start1 = performance.now(); let x1 = 0; for( let i = 0; i < 1e8; i++ ) { x1 += foo(); } let end1 = ( performance.now() - start1 ).toFixed(10); /***/ let start2 = performance.now(); let x2 = 0; for( let i = 0; i < 1e8; i++ ) { x2 += window["foo"](); } let end2 = ( performance.now() - start2 ).toFixed(10); console.log("foo():", end1, " // window: ", end2); } /***/ function foo() { return 1; }
 .as-console-wrapper { max-height: 100vh;important; }

I genuinely expected there to be no difference, but I am seeing the test for NO_WINDOW take 2x the time as WINDOW_STRING or WINDOW_PROPERTY for this simple addition test:

 add = (a,b) => a+b; console.time('NO_WINDOW'); for (var i = 0; i < 1000; i++); add(i, i+1); console.timeEnd('NO_WINDOW'); console.time('WINDOW_STRING'); for (var i = 0; i < 1000; i++); window['add'](i, i+1); console.timeEnd('WINDOW_STRING'); console.time('WINDOW_PROPERTY'); for (var i = 0; i < 1000; i++); window.add(i, i+1); console.timeEnd('WINDOW_PROPERTY');

EDIT: Phil pointed out in the comments that this is seems to be a weird issue with console.timeEnd , where the first call always takes longer than the subsequent ones.

Reproducing with performance.now() and proper benchmarking logic shows no meaningful difference in performance:

 add = (a,b) => a+b; avg = (arr) => arr.reduce(add) / arr.length; let noWindow = [], windowProp = [], windowString = [], n = 1e6, start; start = performance.now(); for (var i = 0; i < n; i++) window.add(i, i+1); windowProp.push(performance.now() - start); start = performance.now(); for (var i = 0; i < n; i++) add(i, i+1); noWindow.push(performance.now() - start); start = performance.now(); for (var i = 0; i < n; i++) window['add'](i, i+1); windowString.push(performance.now() - start); let avgs = [ avg(noWindow), avg(windowString), avg(windowProp) ]; console.log(avgs);

Assuming they're equivalent references, it would seem like the only difference would be in how the variable is read. There have been known to be performance differences in browsers at different points in history when reading globals or object properties using square brackets.

If there is such a difference, it would be negligible, and almost never an issue.

Only thing I would wonder is if some browser loses optimizations for dynamically accessed keys and/or for globals in general. It being a global, and using syntax that dynamically accesses the property, there could be a chance that the function would not get full optimization by the engine.

Again, probably not something that should concern you, unless it's a very heavy function, and quite expensive to run in general.

Depending on the context in which you call it, it is the same thing. In a browser, essentially you can access any of the keys in the window object without directly referencing it. So any of these are the same:

foo(123)
window["foo"](123)
window.foo(123)

Read more about the window object and global functions here .

Depending on how you use it, yes or no. Essentially, there's no difference used once in a program. Repeated millions of times, there's a difference , but it depends on where, how, and how many times, that code is executed. It's quite rare you'd look for pure performance, however.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM