lodashソースの分析は、重い-uniqメソッドです.
4477 ワード
lodash.jsバッグはnode開発でよく使われているjsツールバッグです.中には多くの実用的な方法があります.今日はよく使われている一つの方法を分析します.
使い方
分析
1.下記のコードに注意してください.
2.次にSetを使って重いコードを処理するかどうかの戦略を見ます.
尾
ES 6の出現は本当に大きくて便利なコードの編纂です.ES 6はこんなに便利です.なぜ私はこのような倉庫が好きですか?私の答えは効率的で優雅で安心です.作業時に成熟したライブラリを使用することはコードの品質を保証し、成熟したライブラリは一般的に性能部分を最適化します.
使い方
_.uniq([2, 1, 2])
// => [2, 1]
ソースパッケージ // uniq.js
import baseUniq from './.internal/baseUniq.js'
function uniq(array) {
return (array != null && array.length) ? baseUniq(array) : []
}
export default uniq
uniq関数はここでbaseUniqのパッケージを作っただけですので、引き続きbaseUniqのソースコードを見てください. // baseUniq.js
import SetCache from './SetCache.js'
import arrayIncludes from './arrayIncludes.js'
import arrayIncludesWith from './arrayIncludesWith.js'
import cacheHas from './cacheHas.js'
import createSet from './createSet.js'
import setToArray from './setToArray.js'
const LARGE_ARRAY_SIZE = 200 //
function baseUniq(array, iteratee, comparator) {
let index = -1
let includes = arrayIncludes // , while
let isCommon = true
const { length } = array
const result = []
let seen = result
if (comparator) {
// comparator,
isCommon = false
includes = arrayIncludesWith // includes arrayIncludesWith
}
else if (length >= LARGE_ARRAY_SIZE) { // 200 ,
// , Set ( Set Set )
const set = iteratee ? null : createSet(array)
if (set) {
return setToArray(set) //Set (Set , )
}
isCommon = false //
includes = cacheHas // includes hash
seen = new SetCache // hash
}
else {
// , ,
seen = iteratee ? [] : result
}
outer:
while (++index < length) { //
let value = array[index] //
// ,
const computed = iteratee ? iteratee(value) : value
value = (comparator || value !== 0) ? value : 0
if (isCommon && computed === computed) { //
let seenIndex = seen.length //
while (seenIndex--) { //
if (seen[seenIndex] === computed) { //
continue outer // outer:
}
}
if (iteratee) { //
seen.push(computed) //
}
result.push(value) //
}
// , includes ,
else if (!includes(seen, computed, comparator)) {
if (seen !== result) { // ,result seen
seen.push(computed)
}
result.push(value) //
}
}
return result // ,
}
export default baseUniq
大体の流れ:分析
1.下記のコードに注意してください.
else if (length >= LARGE_ARRAY_SIZE) { // 200 ,
// , Set ( Set Set )
const set = iteratee ? null : createSet(array)
if (set) {
return setToArray(set) //Set (Set , )
}
}
lodashは、現在の配列の長さを判断します.ES 6を呼び出す新しいSetデータタイプを配列した場合、Setタイプに重複する要素は存在しません.つまり、配列のデバックを行い、最後にset ToAray方法を呼び出して配列に戻り、Setタイプは反復可能なタイプであり、...
拡張演算子を使用することができる.性能面では、jsは単一スレッドで実行されるため、大行列の循環がCPU時間を占有し、スレッドがブロックされる.Setタイプを使うと重い仕事を下の階に任せて処理し、性能を向上させます.だから、普段は重い需要がある時にSetタイプのデバックを考慮してもいいです.js実行層でサイクルをするのではなく、性能の最適化です.2.次にSetを使って重いコードを処理するかどうかの戦略を見ます.
outer:
while (++index < length) { //
let value = array[index] //
value = (comparator || value !== 0) ? value : 0
if (isCommon && computed === computed) { //
let seenIndex = seen.length //
while (seenIndex--) { //
if (seen[seenIndex] === computed) { //
continue outer // outer:
}
}
}
}
ここで2つのネストwhileを使って配列を巡回し、重複要素があるかどうかを判断することができます.このような論理は問題なく、通常の動作で最も一般的なデバックコード論理であり、コードの実行時間の複雑さはO(n^2)であり、実行時間は配列の増加に伴って指数レベルが増加するので、なぜlodashのuniq関数は最大の連接可能配列長を規定し、長さを超えてSetデ重量法を採用するのですか?性能の浪費を避ける尾
ES 6の出現は本当に大きくて便利なコードの編纂です.ES 6はこんなに便利です.なぜ私はこのような倉庫が好きですか?私の答えは効率的で優雅で安心です.作業時に成熟したライブラリを使用することはコードの品質を保証し、成熟したライブラリは一般的に性能部分を最適化します.