Skip to content

Instantly share code, notes, and snippets.

@qgustavor
Last active December 14, 2017 11:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qgustavor/d8946c96ab834a1a49a155b246b5937a to your computer and use it in GitHub Desktop.
Save qgustavor/d8946c96ab834a1a49a155b246b5937a to your computer and use it in GitHub Desktop.
let originalArray = [1, 2, 3, 4, 5]
let functions = {
sort: arr => arr.sort(() => Math.random() - 0.5),
swap: arr => {
// Fisher–Yates shuffle
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1))
;[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr
},
mapSort: arr => arr
// set a random value to each element using an array
.map(e => [Math.random(), e])
// sort based on this value
.sort((a, b) => a[0] - b[0])
// then return the original element
.map(e => e[1])
}
Object.entries(functions).forEach(([name, fn]) => {
let resultCounts = {}
console.time('Time elapsed')
for (let i = 0; i < 1000000; i++) {
let shuffledArray = fn(originalArray.slice())
let key = shuffledArray.join('')
resultCounts[key] = (resultCounts[key] || 0) + 1
}
console.log('%s results', name)
console.timeEnd('Time elapsed')
console.table(resultCounts)
})

Results

Considering only the time returned by console.time() and the bias as how many times the most common result was returned more than the least common result. Memory usage wasn't considered.

Sort based shuffle

Took 1261ms to finish. It's biased: the most common result, "21345", showed 67 times more than least common result, "45321".

Fisher–Yates shuffle

Took 846ms to finish. It's not biased: the most common result showed only 1.0667 times more than the least common result.

Map sort based shuffle

Took 1619ms to finish. It's not biased: the most common result showed only 1.0654 times more than the least common result.

Remarks

Sort based shuffle seems intuitive, but as .sort works comparing each array value each other it's slow and, because the comparison changes each time, it's biased. In the other hand the Fisher–Yates shuffle isn't biased and it's fast, but seems it's not too intuitive. The map sort based shuffle uses two maps and a sort, is slower and probably is the one which uses most memory, but isn't biased and it's simple to understand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment