4

I'm looking for a way to avoid the typeof check on every arr[i]

I need to accommodate the fact that arr[i] can be 0

I want to assign arr[i] = num if arr[i] is undefined or greater than num

neaumusic
  • 10,027
  • 9
  • 55
  • 83
  • 1
    Why would it be `undefined` in the first place? Doesn't seem like a useful value to have in an Array of numbers. Either way, there's no need for `typeof` to check for `undefined`. –  Dec 25 '15 at 03:03
  • 2
    How about this: `arr[i] = Math.max(arr[i] || 0, num)` – ninhjs.dev Dec 25 '15 at 06:01
  • Why would you need to make such simple logic faster in the first place? It ain't gonna get much faster than that. You can try something like `if(!(num >= arr[i])){arr[i]=num;}` though to invert what happens for the case of it being undefined. – Ultimater Dec 25 '15 at 07:53

3 Answers3

2

The way to answer performance questions is to run benchmarks.

There are four alternatives:

  1. arr[i] === undefined || num < arr[i]

  2. typeof arr[i] === 'undefined' || num < arr[i]

  3. !(i in arr) || num < arr[i]. This assumes the undefined values are true "holes" (missing indexes), rather than indexes that are present but have a value of undefined.

  4. !(num >= arr[i]). This takes advantage of the fact that comparisons with undefined return false.

1 and 2 are equivalent performance-wise. 3 is about 20 times slower. 4 is about 20% slower. Using isNaN as suggested in another answer is about 50% slower.

Therefore, if you are interested purely in performance, use 1 or 2. If you want to save keystrokes, at a minor performance cost, use 4. However, 4 is also less readable and you probably will have to add a comment about how it handles undefined, which will negate any keystroke savings.

See http://jsperf.com/ways-to-check-for-undefined/4.

1

Try this:

arr[i] == undefined || num < arr[i]

or

arr[i]=(arr[i] >= 0 && arr [i] < num) ? arr[i] : num;

Or

arr[i]=(!isNaN(arr[i]) && arr [i] < num) ? arr[i] : num;
hichris123
  • 10,145
  • 15
  • 56
  • 70
Manivannan
  • 3,074
  • 3
  • 21
  • 32
  • This will replace negative values of `arr[i]` with `num`, which probably is not what the OP intended. –  Dec 25 '15 at 06:12
  • For this case you can try with isNaN method – Manivannan Dec 25 '15 at 07:04
  • 2
    `isNaN` seems to be about 50% slower than a direct check for `undefined`. See http://jsperf.com/ways-to-check-for-undefined/5. –  Dec 25 '15 at 07:28
  • Oh thanks for update.. For this case, Your 1st option is cool but my suggetion is not to check type `arr[i] == undefined || num < arr[i]` – Manivannan Dec 25 '15 at 13:46
1

Checking something === something_else is as fast as it gets, but what does make your code slower is the fact that you are doing two things instead of one:

You are checking both typeof arr[i] === “undefined” and num < arr[i] even though javascript engine is going to check data type anyway.

What I mean is, if it is true that typeof arr[i] === “undefined”, then num < arr[i] will always be false. It would also be false for >=, which leads to the solution.

Instead of:

if (typeof arr[i] === “undefined” || num < arr[i])

You can do:

if (!(num >= arr[i]))

On the other hand...

  • if you don't know that it is currently too slow, which you don't if you did not profile it, then you should not optimize it. See: When is optimisation premature?

  • why do you even have undefined data in the list to begin with? Couldn't you filter that out before writing into the list, rather than at reading time? It is a good idea to always have only one data type in a contaioner (unless you have a really good reason otherwise)

  • if you have a key->value mapping with some keys not defined, maybe Array is not the right container for your use case

Community
  • 1
  • 1
zvone
  • 18,045
  • 3
  • 49
  • 77