jonschlinkert / kind-of

Get the native JavaScript type of a value, fast. Used by superstruct, micromatch and many others!
https://github.com/jonschlnkert
MIT License
347 stars 38 forks source link

Adding ArrayBuffer, DataView, adding slight Optimizations #6

Closed TheIronDev closed 7 years ago

TheIronDev commented 8 years ago

Adding ArrayBuffer and DataView to the kindOf check.

Also, rather than if-checking each of the types, I've thrown them into a map. 1 if-check probably faster than 19 if-checks (not by much, but it looks cleaner :).

if (type ==='A') {
    return 'a';
}
if (type === 'B') {
    return 'b';
}

Turns into:

var typeMap = {
    A: 'a',
    B: 'b'
};
if (typeMap[type]) {
    return typeMap[type];
}

The order of checks has been mostly been maintained, but I did put the Buffer check above the RegExp, Date, and Arguments to simplify stuff.

If the order is a problem let me know and I can split the typeMap into two parts (before the Buffer check and after).

jonschlinkert commented 8 years ago

Hi, thanks for the pr, just curious if you ran the benchmarks after making changes. I'd be surprised if that was faster, generally array lookups will be a lot slower than type checking

TheIronDev commented 8 years ago

I haven't been able to get the benchmarks to work properly, I see the following results:

#1: arguments 
  current: 
  libTypeOf: 
  libTypeof: 

  fastest is 
#2: array 
  current: 
  libTypeOf: 
  libTypeof: 
// ...

As for the lookups, its just doing a property lookup, which I assumed would be faster than multiple if-checks, but... I'll try and get benchmarks up and running so we can know for sure 👍

TheIronDev commented 8 years ago

Looks like the current version of benchmarked was breaking. I npm install benchmarked@0.1.3 and everything started working again, benchmarks coming right up!

TheIronDev commented 8 years ago

Alright, I ran benchmarks, and got results that were roughly the same.

I then went back and replaced the object literal with a prototype-less object, which speeds up prop checks (it doesn't need to go down the prototype chain.)

Here are the benchmark results that I last saw (using benchmarked@0.1.3):

#1: arguments.js 
  current.js x 2,433,167 ops/sec ±1.29% (93 runs sampled)
  lib-type-of.js x 3,863,109 ops/sec ±1.15% (95 runs sampled)
  lib-typeof.js x 8,128,220 ops/sec ±2.38% (92 runs sampled)

  fastest is lib-typeof.js
#2: array.js 
  current.js x 19,898,583 ops/sec ±1.79% (85 runs sampled)
  lib-type-of.js x 2,689,094 ops/sec ±1.75% (91 runs sampled)
  lib-typeof.js x 7,755,975 ops/sec ±1.31% (89 runs sampled)

  fastest is current.js
#3: boolean.js 
  current.js x 24,984,094 ops/sec ±1.38% (95 runs sampled)
  lib-type-of.js x 3,052,789 ops/sec ±1.30% (96 runs sampled)
  lib-typeof.js x 8,756,968 ops/sec ±1.66% (94 runs sampled)

  fastest is current.js
#4: buffer.js 
  current.js x 16,075,789 ops/sec ±1.41% (94 runs sampled)
  lib-type-of.js x 3,839,853 ops/sec ±1.27% (97 runs sampled)
  lib-typeof.js x 8,111,971 ops/sec ±1.51% (94 runs sampled)

  fastest is current.js
#5: date.js 
  current.js x 20,136,093 ops/sec ±1.13% (93 runs sampled)
  lib-type-of.js x 4,830,488 ops/sec ±1.63% (93 runs sampled)
  lib-typeof.js x 8,175,429 ops/sec ±0.85% (96 runs sampled)

  fastest is current.js
#6: function.js 
  current.js x 18,492,513 ops/sec ±2.28% (84 runs sampled)
  lib-type-of.js x 4,109,333 ops/sec ±2.11% (89 runs sampled)
  lib-typeof.js x 9,324,577 ops/sec ±1.15% (87 runs sampled)

  fastest is current.js
#7: map.js 
  current.js x 2,675,638 ops/sec ±0.68% (99 runs sampled)
  lib-type-of.js x 5,017,445 ops/sec ±0.75% (94 runs sampled)
  lib-typeof.js x 7,273,848 ops/sec ±1.63% (87 runs sampled)

  fastest is lib-typeof.js
#8: null.js 
  current.js x 25,426,259 ops/sec ±2.14% (84 runs sampled)
  lib-type-of.js x 10,889,739 ops/sec ±1.47% (90 runs sampled)
  lib-typeof.js x 9,029,230 ops/sec ±1.54% (87 runs sampled)

  fastest is current.js
#9: number.js 
  current.js x 21,215,842 ops/sec ±1.20% (89 runs sampled)
  lib-type-of.js x 2,167,992 ops/sec ±1.27% (88 runs sampled)
  lib-typeof.js x 2,955,658 ops/sec ±1.47% (89 runs sampled)

  fastest is current.js
#10: object.js 
  current.js x 2,925,517 ops/sec ±1.14% (90 runs sampled)
  lib-type-of.js x 2,621,443 ops/sec ±1.17% (92 runs sampled)
  lib-typeof.js x 7,935,123 ops/sec ±1.21% (90 runs sampled)

  fastest is lib-typeof.js
#11: regex.js 
  current.js x 17,656,361 ops/sec ±1.26% (91 runs sampled)
  lib-type-of.js x 3,994,845 ops/sec ±1.00% (91 runs sampled)
  lib-typeof.js x 6,717,681 ops/sec ±1.46% (90 runs sampled)

  fastest is current.js
#12: set.js 
  current.js x 2,436,355 ops/sec ±1.23% (92 runs sampled)
  lib-type-of.js x 5,046,422 ops/sec ±1.40% (90 runs sampled)
  lib-typeof.js x 7,841,817 ops/sec ±0.84% (93 runs sampled)

  fastest is lib-typeof.js
#13: string.js 
  current.js x 24,870,908 ops/sec ±1.31% (93 runs sampled)
  lib-type-of.js x 3,350,431 ops/sec ±1.36% (97 runs sampled)
  lib-typeof.js x 8,197,749 ops/sec ±0.69% (98 runs sampled)

  fastest is current.js
#14: symbol.js 
  current.js x 1,641,341 ops/sec ±0.74% (96 runs sampled)
  lib-type-of.js x 2,355,337 ops/sec ±1.19% (93 runs sampled)
  lib-typeof.js x 8,488,637 ops/sec ±0.86% (98 runs sampled)

  fastest is lib-typeof.js
#15: template-strings.js 
  current.js x 21,843,554 ops/sec ±0.73% (97 runs sampled)
  lib-type-of.js x 3,381,650 ops/sec ±1.00% (97 runs sampled)
  lib-typeof.js x 8,040,660 ops/sec ±0.95% (92 runs sampled)

  fastest is current.js
#16: undef.js 
  current.js x 18,056,143 ops/sec ±0.74% (96 runs sampled)
  lib-type-of.js x 10,765,761 ops/sec ±0.76% (93 runs sampled)
  lib-typeof.js x 17,735,961 ops/sec ±0.85% (95 runs sampled)

  fastest is current.js
#17: weakmap.js 
  current.js x 2,145,284 ops/sec ±0.74% (99 runs sampled)
  lib-type-of.js x 4,089,179 ops/sec ±0.94% (93 runs sampled)
  lib-typeof.js x 7,344,955 ops/sec ±0.70% (93 runs sampled)

  fastest is lib-typeof.js
#18: weakset.js 
  current.js x 1,800,597 ops/sec ±1.02% (93 runs sampled)
  lib-type-of.js x 3,775,689 ops/sec ±0.85% (99 runs sampled)
  lib-typeof.js x 7,320,458 ops/sec ±1.19% (97 runs sampled)

  fastest is lib-typeof.js

Which appears to perform slightly better than right before this commit.

jonschlinkert commented 8 years ago

thanks for going through the trouble! I'll pull this down and take a look today.

jonschlinkert commented 8 years ago

1 if-check probably faster than 19 if-checks (not by much, but it looks cleaner :).

well, technically the point the of having the separate if checks is to exist as early as possible. sometimes ugly code is more performant. so ugly is okay lol, because the other point is that we want it to be as stable and explicit as possible so we don't ever have to look at it ;)

jonschlinkert commented 7 years ago

I'm going to pass on this, but I do appreciate the pr. thanks again