0

How much slower faster is the typeof operator than a function call? Or is it negligible and micro-optimising?

if (isNumber(myVar)) {
}

if (typeof myVar === 'number') {
}
Richard
  • 4,809
  • 3
  • 27
  • 46
  • 5
    Test it and find out? – David Jul 09 '16 at 16:24
  • 1
    I wouldn't perform so many type checks in the first place. –  Jul 09 '16 at 16:24
  • 2
    Seeing as `isNumber` is `undefined` and would just throw an error, it should be much faster than actually checking the string – adeneo Jul 09 '16 at 16:24
  • 1
    In practice, the difference is negligible even at the nanosecond level due to function inlining among a whole barrage of other optimizations. Even IE will likely inline that, and I don't know of any interpreter that wouldn't. – Claudia Jul 09 '16 at 16:28
  • 1
    Mentioning from what @adeneo stated. We need to know how you defined your function call to really answer that question. – Spencer Wieczorek Jul 09 '16 at 16:30
  • If you want to compose use the function, otherwise use the operator. –  Jul 09 '16 at 16:37
  • @IsiahMeadows Is there a limit on how big the function is as to whether it gets inlined or not? – Richard Jul 09 '16 at 17:09
  • I don't know about other browsers/engines, but at least in V8 (Chrome/Opera/Node, as of V8 version 5.0.71.47), there's a few hard limits: 600 raw bytes, 196 max AST nodes in a single function, and 400 cumulative nodes, including other inlined functions. I also believe there's a hard, non-configurable limit of 4-5 (if I recall correctly) nested inlined functions before it stops. It also takes some time before any function becomes a candidate of inlining (it can literally take upwards of a thousand in some cases), and there's several other variables the engine must also consider first. – Claudia Jul 09 '16 at 17:20

2 Answers2

4

Or is it negligible and micro-optimising?

Yes, this is definitely something to worry about if and only if you identify the code in question as being a performance bottleneck, which is really unlikely. It's micro-optimization. Function calls are really, really fast even if they don't get optimized out by the JavaScript engine. I used to worry about function call overhead when Array#forEach first appeared on the scene. Even back then, it wasn't an issue, even on the oldest, slowest JavaScript interpreter I could find: The one in IE6. Details on my blog: foreach and runtime cost

Re whether it takes longer... How long is a piece of string? It totally depends on the JavaScript engine you're using and whether the code in question is identified as a "hot" spot by the engine (assuming it's an engine like V8 that works in stages and optimizes hot spots).

A modern engine is likely to inline that if it becomes important to do so. That is not a guarantee.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • In a minimal case like this, you can pretty much guarantee it'll be inlined within a few dozen or so calls in any modern engine capable of function inlining, unless you're running a super trivial script that only uses it a couple times. – Claudia Jul 09 '16 at 16:31
  • 1
    @IsiahMeadows: Citation? I very much doubt it would take only a couple of dozen calls (not that it really matters). Remember the V8 crankshaft bug with `typeof null`? Typically took hundreds or even thousands of calls in a tight loop before V8 kicked crankshaft in to optimize it and the bug manifested. – T.J. Crowder Jul 09 '16 at 16:39
  • Okay...I probably don't remember the exact threshold (and you're correct in that I'm off by quite a bit), but it usually gets inlined if the code is on any sort of hot path. – Claudia Jul 09 '16 at 16:42
3

Or is it negligible and micro-optimising?

It's negligible and micro-optimizing.


If you want to check if something's a number, I recommend using an isNaN check and then casting to a number.

if (!isNaN(myVar)) {
  myVar = +myVar;
}

In this way, you don't actually care how the value gets treated as a number.

Someone using the API could then choose to pass an object that can be treated as a number:

myVar = {
  valueOf: function () {
    return 5;
  }
};
zzzzBov
  • 174,988
  • 54
  • 320
  • 367
  • don't bother to check wether `myVar` actually isNaN, just cast it! It's so freaking fast, that it doesn't matter wether you do it to an actual Number. And it cleans up your code, wich is way more important. Usually you have to worry way more about real `NaN`-values in your calculations, so my code usually looks like `myVar = +myVar||0;` – Thomas Jul 09 '16 at 16:36
  • @Thomas If you want to avoid all incorrect automatic conversions of falsy values, see [CMS's answer](http://stackoverflow.com/a/1830844/1169519). – Teemu Jul 09 '16 at 16:41
  • 1
    @Thomas No, it's more important for the code to be correct. Several data types can cast for a number, but it doesn't mean they are a number. For example, a string isn't a number. – Spencer Wieczorek Jul 09 '16 at 16:43
  • @Thomas, the point was to match the question. Without more context I can't give much in the way of suggestions. Sometimes you want to have a parameter that behaves one way as a number and another as a string. They're certainly not common, but not unheard of. – zzzzBov Jul 09 '16 at 19:00