Skip to content

Commit 48c8108

Browse files
committed
perf: do not lowercase returned values
We're sacrificing a lot of performance just to lowercase the string values, which is not ideal as it's not always necessary. Here are some numbers demonstrating the difference in performance: With `.toLowerCase()`: ``` string literal x 31,742,089 ops/sec ±6.85% (70 runs sampled) array literal x 12,508,545 ops/sec ±3.86% (67 runs sampled) boolean literal x 33,502,011 ops/sec ±3.58% (66 runs sampled) object literal x 1,178,855 ops/sec ±2.06% (79 runs sampled) object from null x 3,356,249 ops/sec ±2.03% (81 runs sampled) regex literal x 2,738,477 ops/sec ±1.95% (80 runs sampled) number literal x 30,119,855 ops/sec ±2.04% (78 runs sampled) promise x 7,260,140 ops/sec ±1.79% (81 runs sampled) null x 34,793,675 ops/sec ±1.58% (84 runs sampled) undefined x 31,537,228 ops/sec ±1.77% (81 runs sampled) function x 35,571,426 ops/sec ±1.69% (82 runs sampled) buffer x 5,468,033 ops/sec ±2.19% (83 runs sampled) date x 4,402,505 ops/sec ±1.47% (83 runs sampled) error x 932,833 ops/sec ±2.16% (80 runs sampled) map x 7,298,659 ops/sec ±1.64% (81 runs sampled) regex constructor x 3,042,918 ops/sec ±2.28% (80 runs sampled) set x 6,075,985 ops/sec ±1.91% (82 runs sampled) string constructor x 1,077,682 ops/sec ±2.32% (82 runs sampled) weakmap x 5,949,120 ops/sec ±1.99% (83 runs sampled) weakset x 5,574,794 ops/sec ±1.89% (78 runs sampled) arguments x 1,065,249 ops/sec ±1.37% (83 runs sampled) arrow function x 28,776,605 ops/sec ±1.61% (81 runs sampled) generator function x 34,581,601 ops/sec ±2.11% (79 runs sampled) Float64Array x 5,306,129 ops/sec ±1.64% (83 runs sampled) Float32Array x 5,635,134 ops/sec ±1.37% (84 runs sampled) Uint32Array x 5,584,889 ops/sec ±1.72% (83 runs sampled) Uint16Array x 5,024,561 ops/sec ±1.40% (85 runs sampled) Uint8Array x 5,032,024 ops/sec ±1.93% (81 runs sampled) Int32Array x 6,261,825 ops/sec ±2.21% (78 runs sampled) Int16Array x 6,380,182 ops/sec ±1.68% (81 runs sampled) Int8Array x 6,156,981 ops/sec ±2.27% (78 runs sampled) Uint8ClampedArray x 5,911,482 ops/sec ±1.85% (80 runs sampled) DataView x 7,308,534 ops/sec ±1.83% (78 runs sampled) ``` Without `.toLowerCase()`: ``` string literal x 47,522,814 ops/sec ±1.93% (80 runs sampled) array literal x 18,729,054 ops/sec ±1.88% (81 runs sampled) boolean literal x 33,037,749 ops/sec ±2.17% (83 runs sampled) object literal x 1,536,749 ops/sec ±2.99% (80 runs sampled) object from null x 3,148,007 ops/sec ±2.39% (83 runs sampled) regex literal x 3,373,384 ops/sec ±1.82% (82 runs sampled) number literal x 33,096,650 ops/sec ±1.43% (85 runs sampled) promise x 13,416,347 ops/sec ±1.62% (80 runs sampled) null x 32,376,000 ops/sec ±1.70% (82 runs sampled) undefined x 30,734,992 ops/sec ±1.60% (82 runs sampled) function x 35,044,726 ops/sec ±1.87% (81 runs sampled) buffer x 10,831,858 ops/sec ±1.93% (82 runs sampled) date x 4,511,245 ops/sec ±1.99% (81 runs sampled) error x 836,481 ops/sec ±2.31% (79 runs sampled) map x 14,289,403 ops/sec ±1.72% (83 runs sampled) regex constructor x 3,764,635 ops/sec ±2.69% (78 runs sampled) set x 12,494,254 ops/sec ±1.95% (82 runs sampled) string constructor x 1,282,794 ops/sec ±1.92% (80 runs sampled) weakmap x 15,418,935 ops/sec ±1.84% (79 runs sampled) weakset x 14,768,545 ops/sec ±1.60% (82 runs sampled) arguments x 993,064 ops/sec ±1.88% (81 runs sampled) arrow function x 30,511,620 ops/sec ±2.07% (79 runs sampled) generator function x 35,487,241 ops/sec ±1.53% (81 runs sampled) Float64Array x 9,666,668 ops/sec ±1.75% (79 runs sampled) Float32Array x 9,286,265 ops/sec ±1.66% (81 runs sampled) Uint32Array x 9,352,490 ops/sec ±1.37% (82 runs sampled) Uint16Array x 8,404,961 ops/sec ±2.03% (80 runs sampled) Uint8Array x 8,635,152 ops/sec ±1.81% (80 runs sampled) Int32Array x 10,569,543 ops/sec ±1.67% (82 runs sampled) Int16Array x 9,444,358 ops/sec ±1.53% (80 runs sampled) Int8Array x 7,235,174 ops/sec ±2.43% (76 runs sampled) Uint8ClampedArray x 8,055,645 ops/sec ±1.67% (82 runs sampled) DataView x 15,014,475 ops/sec ±2.08% (79 runs sampled) ``` BREAKING CHANGE: All strings will no longer be lowercase. If you want them in lowercase, simply add `.toLowerCase()` to the return value.
1 parent 97e785b commit 48c8108

File tree

5 files changed

+217
-209
lines changed

5 files changed

+217
-209
lines changed

README.md

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,15 @@ var type = require('type-detect');
104104
#### array
105105

106106
```js
107-
assert(type([]) === 'array');
108-
assert(type(new Array()) === 'array');
107+
assert(type([]) === 'Array');
108+
assert(type(new Array()) === 'Array');
109109
```
110110

111111
#### regexp
112112

113113
```js
114-
assert(type(/a-z/gi) === 'regexp');
115-
assert(type(new RegExp('a-z')) === 'regexp');
114+
assert(type(/a-z/gi) === 'RegExp');
115+
assert(type(new RegExp('a-z')) === 'RegExp');
116116
```
117117

118118
#### function
@@ -132,7 +132,7 @@ assert(type(function () {}) === 'function');
132132
#### date
133133

134134
```js
135-
assert(type(new Date) === 'date');
135+
assert(type(new Date) === 'Date');
136136
```
137137

138138
#### number
@@ -144,14 +144,14 @@ assert(type(-1) === 'number');
144144
assert(type(-1.234) === 'number');
145145
assert(type(Infinity) === 'number');
146146
assert(type(NaN) === 'number');
147-
assert(type(new Number(1)) === 'number');
147+
assert(type(new Number(1)) === 'Number'); // note - the object version has a capital N
148148
```
149149

150150
#### string
151151

152152
```js
153153
assert(type('hello world') === 'string');
154-
assert(type(new String('hello')) === 'string');
154+
assert(type(new String('hello')) === 'String'); // note - the object version has a capital S
155155
```
156156

157157
#### null
@@ -172,34 +172,34 @@ assert(type(null) !== 'undefined');
172172

173173
```js
174174
var Noop = function () {};
175-
assert(type({}) === 'object');
176-
assert(type(Noop) !== 'object');
177-
assert(type(new Noop) === 'object');
178-
assert(type(new Object) === 'object');
175+
assert(type({}) === 'Object');
176+
assert(type(Noop) !== 'Object');
177+
assert(type(new Noop) === 'Object');
178+
assert(type(new Object) === 'Object');
179179
```
180180

181181
#### ECMA6 Types
182182

183183
All new ECMAScript 2015 objects are also supported, such as Promises and Symbols:
184184

185185
```js
186-
assert(type(new Map() === 'map');
187-
assert(type(new WeakMap()) === 'weakmap');
188-
assert(type(new Set()) === 'set');
189-
assert(type(new WeakSet()) === 'weakset');
190-
assert(type(Symbol()) === 'symbol');
191-
assert(type(new Promise(callback) === 'promise');
192-
assert(type(new Int8Array()) === 'int8array');
193-
assert(type(new Uint8Array()) === 'uint8array');
194-
assert(type(new UInt8ClampedArray()) === 'uint8clampedarray');
195-
assert(type(new Int16Array()) === 'int16array');
196-
assert(type(new Uint16Array()) === 'uint16array');
197-
assert(type(new Int32Array()) === 'int32array');
198-
assert(type(new UInt32Array()) === 'uint32array');
199-
assert(type(new Float32Array()) === 'float32array');
200-
assert(type(new Float64Array()) === 'float64array');
201-
assert(type(new ArrayBuffer()) === 'arraybuffer');
202-
assert(type(new DataView(arrayBuffer)) === 'dataview');
186+
assert(type(new Map() === 'Map');
187+
assert(type(new WeakMap()) === 'WeakMap');
188+
assert(type(new Set()) === 'Set');
189+
assert(type(new WeakSet()) === 'WeakSet');
190+
assert(type(Symbol()) === 'Symbol');
191+
assert(type(new Promise(callback) === 'Promise');
192+
assert(type(new Int8Array()) === 'Int8Array');
193+
assert(type(new Uint8Array()) === 'Uint8Array');
194+
assert(type(new UInt8ClampedArray()) === 'Uint8ClampedArray');
195+
assert(type(new Int16Array()) === 'Int16Array');
196+
assert(type(new Uint16Array()) === 'Uint16Array');
197+
assert(type(new Int32Array()) === 'Int32Array');
198+
assert(type(new UInt32Array()) === 'Uint32Array');
199+
assert(type(new Float32Array()) === 'Float32Array');
200+
assert(type(new Float64Array()) === 'Float64Array');
201+
assert(type(new ArrayBuffer()) === 'ArrayBuffer');
202+
assert(type(new DataView(arrayBuffer)) === 'DataView');
203203
```
204204
205205
Also, if you use `Symbol.toStringTag` to change an Objects return value of the `toString()` Method, `type()` will return this value, e.g:

index.js

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ module.exports = function typeDetect(obj) {
9595
* array literal x 22,479,650 ops/sec ±0.96% (81 runs sampled)
9696
*/
9797
if (isArrayExists && Array.isArray(obj)) {
98-
return 'array';
98+
return 'Array';
9999
}
100100

101101
if (isDom) {
@@ -107,7 +107,7 @@ module.exports = function typeDetect(obj) {
107107
* - IE Edge <=13 === "[object Object]"
108108
*/
109109
if (obj === globalObject.location) {
110-
return 'location';
110+
return 'Location';
111111
}
112112

113113
/* ! Spec Conformance
@@ -130,7 +130,7 @@ module.exports = function typeDetect(obj) {
130130
* - IE Edge <=13 === "[object HTMLDocument]"
131131
*/
132132
if (obj === globalObject.document) {
133-
return 'document';
133+
return 'Document';
134134
}
135135

136136
/* ! Spec Conformance
@@ -140,7 +140,7 @@ module.exports = function typeDetect(obj) {
140140
* - IE <=10 === "[object MSMimeTypesCollection]"
141141
*/
142142
if (obj === (globalObject.navigator || {}).mimeTypes) {
143-
return 'mimetypearray';
143+
return 'MimeTypeArray';
144144
}
145145

146146
/* ! Spec Conformance
@@ -150,7 +150,7 @@ module.exports = function typeDetect(obj) {
150150
* - IE <=10 === "[object MSPluginsCollection]"
151151
*/
152152
if (obj === (globalObject.navigator || {}).plugins) {
153-
return 'pluginarray';
153+
return 'PluginArray';
154154
}
155155

156156
/* ! Spec Conformance
@@ -160,7 +160,7 @@ module.exports = function typeDetect(obj) {
160160
* - IE <=10 === "[object HTMLBlockElement]"
161161
*/
162162
if (htmlElementExists && obj instanceof HTMLElement && obj.tagName === 'BLOCKQUOTE') {
163-
return 'htmlquoteelement';
163+
return 'HTMLQuoteElement';
164164
}
165165

166166
/* ! Spec Conformance
@@ -176,7 +176,7 @@ module.exports = function typeDetect(obj) {
176176
* - Safari === "[object HTMLTableCellElement]"
177177
*/
178178
if (htmlElementExists && obj instanceof HTMLElement && obj.tagName === 'TD') {
179-
return 'htmltabledatacellelement';
179+
return 'HTMLTableDataCellElement';
180180
}
181181

182182
/* ! Spec Conformance
@@ -192,7 +192,7 @@ module.exports = function typeDetect(obj) {
192192
* - Safari === "[object HTMLTableCellElement]"
193193
*/
194194
if (htmlElementExists && obj instanceof HTMLElement && obj.tagName === 'TH') {
195-
return 'htmltableheadercellelement';
195+
return 'HTMLTableHeaderCellElement';
196196
}
197197
}
198198

@@ -220,7 +220,7 @@ module.exports = function typeDetect(obj) {
220220
*/
221221
var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]);
222222
if (typeof stringTag === 'string') {
223-
return stringTag.toLowerCase();
223+
return stringTag;
224224
}
225225

226226
if (getPrototypeOfExists) {
@@ -234,7 +234,7 @@ module.exports = function typeDetect(obj) {
234234
* regex constructor x 3,931,108 ops/sec ±0.58% (84 runs sampled)
235235
*/
236236
if (objPrototype === RegExp.prototype) {
237-
return 'regexp';
237+
return 'RegExp';
238238
}
239239

240240
/* ! Speed optimisation
@@ -244,7 +244,7 @@ module.exports = function typeDetect(obj) {
244244
* date x 3,953,779 ops/sec ±1.35% (77 runs sampled)
245245
*/
246246
if (objPrototype === Date.prototype) {
247-
return 'date';
247+
return 'Date';
248248
}
249249

250250
/* ! Spec Conformance
@@ -257,7 +257,7 @@ module.exports = function typeDetect(obj) {
257257
* - Safari 7.1-Latest === "[object Promise]"
258258
*/
259259
if (promiseExists && objPrototype === Promise.prototype) {
260-
return 'promise';
260+
return 'Promise';
261261
}
262262

263263
/* ! Speed optimisation
@@ -267,7 +267,7 @@ module.exports = function typeDetect(obj) {
267267
* set x 4,545,879 ops/sec ±1.13% (83 runs sampled)
268268
*/
269269
if (setExists && objPrototype === Set.prototype) {
270-
return 'set';
270+
return 'Set';
271271
}
272272

273273
/* ! Speed optimisation
@@ -277,7 +277,7 @@ module.exports = function typeDetect(obj) {
277277
* map x 4,183,945 ops/sec ±6.59% (82 runs sampled)
278278
*/
279279
if (mapExists && objPrototype === Map.prototype) {
280-
return 'map';
280+
return 'Map';
281281
}
282282

283283
/* ! Speed optimisation
@@ -287,7 +287,7 @@ module.exports = function typeDetect(obj) {
287287
* weakset x 4,237,510 ops/sec ±2.01% (77 runs sampled)
288288
*/
289289
if (weakSetExists && objPrototype === WeakSet.prototype) {
290-
return 'weakset';
290+
return 'WeakSet';
291291
}
292292

293293
/* ! Speed optimisation
@@ -297,7 +297,7 @@ module.exports = function typeDetect(obj) {
297297
* weakmap x 3,881,384 ops/sec ±1.45% (82 runs sampled)
298298
*/
299299
if (weakMapExists && objPrototype === WeakMap.prototype) {
300-
return 'weakmap';
300+
return 'WeakMap';
301301
}
302302

303303
/* ! Spec Conformance
@@ -307,7 +307,7 @@ module.exports = function typeDetect(obj) {
307307
* - Edge <=13 === "[object Object]"
308308
*/
309309
if (dataViewExists && objPrototype === DataView.prototype) {
310-
return 'dataview';
310+
return 'DataView';
311311
}
312312

313313
/* ! Spec Conformance
@@ -317,7 +317,7 @@ module.exports = function typeDetect(obj) {
317317
* - Edge <=13 === "[object Object]"
318318
*/
319319
if (mapExists && objPrototype === mapIteratorPrototype) {
320-
return 'map iterator';
320+
return 'Map Iterator';
321321
}
322322

323323
/* ! Spec Conformance
@@ -327,7 +327,7 @@ module.exports = function typeDetect(obj) {
327327
* - Edge <=13 === "[object Object]"
328328
*/
329329
if (setExists && objPrototype === setIteratorPrototype) {
330-
return 'set iterator';
330+
return 'Set Iterator';
331331
}
332332

333333
/* ! Spec Conformance
@@ -337,7 +337,7 @@ module.exports = function typeDetect(obj) {
337337
* - Edge <=13 === "[object Object]"
338338
*/
339339
if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) {
340-
return 'array iterator';
340+
return 'Array Iterator';
341341
}
342342

343343
/* ! Spec Conformance
@@ -347,7 +347,7 @@ module.exports = function typeDetect(obj) {
347347
* - Edge <=13 === "[object Object]"
348348
*/
349349
if (stringIteratorExists && objPrototype === stringIteratorPrototype) {
350-
return 'string iterator';
350+
return 'String Iterator';
351351
}
352352

353353
/* ! Speed optimisation
@@ -357,16 +357,15 @@ module.exports = function typeDetect(obj) {
357357
* object from null x 5,838,000 ops/sec ±0.99% (84 runs sampled)
358358
*/
359359
if (objPrototype === null) {
360-
return 'object';
360+
return 'Object';
361361
}
362362
}
363363

364364
return Object
365365
.prototype
366366
.toString
367367
.call(obj)
368-
.slice(toStringLeftSliceLength, toStringRightSliceLength)
369-
.toLowerCase();
368+
.slice(toStringLeftSliceLength, toStringRightSliceLength);
370369
};
371370

372371
module.exports.typeDetect = module.exports;

0 commit comments

Comments
 (0)