How to sort your socks using JS

How to sort your socks using JS

No matter your experience in JS, you have probably came across the Array#sort method at some point. Do you remember the first time you tried sorting numbers? You were probably astonished that the sort method does not sort things out quite as we might expect. Believe it or not, there is actually much more going on than meets the eye! Let’s get our computer science hat on and explore some useful sorting algorithms currently implemented by JS engines used by Node such as Chrome's V8 and Microsoft's Chakra. As a developer, learning how these algorithms work, why and when to use them will help you create more performant and consistent applications!

7c917eac018306e411041d5533910807?s=128

Claudia Hernández

June 01, 2018
Tweet

Transcript

  1. HOW TO SORT YOUR SOCKS USING JAVASCRIPT? Claudia Hernandez -

    AmsterdamJS
  2. CS 101
 Intro to computational complexity: The Sorting Problem

  3. @koste4 http://www.bbc.com/news/magazine-37196037

  4. @koste4 ¿WHAT DOES A PILE OF DIRTY SOCKS NAPOLEON STRATEGIES

    & ROMANIAN FOLK
 DANCE , HAVE IN COMMON?
  5. @koste4 COMPUTATIONAL
 COMPLEXITY Study of all the possible algorithms that

    can solve a problem
  6. @koste4 Algorithm that sorts elements of a list according to

    a certain order. The most commonly used orders are numerical & lexicographical SORTING ALGORTHIM
  7. @koste4 ARRAY SORT IN JS # 1 myArray = [33,

    2, 98, 25, 4] 2 myArray.sort() // [ 2, 25, 33, 4, 98 ]
  8. @koste4 LEXICOGRAPHICAL SORTING “If compareFunction is not supplied, elements are

    sorted by converting them to strings and comparing strings in Unicode code point value” compareFunction D
  9. @koste4 UNICODE VALUE 1 colors = ['red', 'blue'] 2 colors.sort()

    3 // ['blue', 'red'] 4 5 numbers = [80, 9] 6 numbers.sort() 7 // [80, 9] 80 = = 56 48 57 00 9
  10. @koste4 1 colors = ['red', 'blue'] 2 colors.sort() 3 //

    ['blue', 'red'] 4 5 numbers = ['80', '9'] 6 numbers.sort() 7 // [80, 9] 80 = = 56 48 57 00 9 UNICODE VALUE
  11. @koste4 ARRAY SORT IN JS # 1 // [ 2,

    25, 33, 4, 98 ]
  12. @koste4 ARRAY SORT IN JS # 1 emojis = ["",

    "", ""] 2 emojis.sort() // [ "", "", ""] 4 5 wtfJavascript = [390, "", 1, "2325"] 6 wtfJavascript.sort() // [ 1, "235", 390, ""]
  13. @koste4 ARRAY SORT IN JS # 1 myArray = [33,

    2, 98, 25, 4] 2 myArray.sort( (a,b) => a - b ) 3 // [ 2, 4, 25, 33, 98 ]
  14. @koste4 ¿HAVE YOU EVER WHICH WONDERED ALGORITHIM IS USED IN

    JAVASCRIPT’S NATIVE SORT FUNCTION ? JAVASCRIPT
  15. https://hg.mozilla.org/mozilla-central/file/28be8df0deb7/js/src/jsarray.cpp M E R G E S O R T

    S O R T S P I D E R 
 M O N K E Y
  16. https://hg.mozilla.org/mozilla-central/file/28be8df0deb7/js/src/jsarray.cpp M E R G E S O R T

    S O R T S P I D E R 
 M O N K E Y
  17. https://hg.mozilla.org/mozilla-central/file/28be8df0deb7/js/src/jsarray.cpp M E R G E S O R T

    S O R T S P I D E R 
 M O N K E Y
  18. https://github.com/v8/v8/blob/master/src/js/array.js Q U I C K S O R T

    S O R T V 8
  19. https://github.com/v8/v8/blob/master/src/js/array.js Q U I C K S O R T

    S O R T V 8
  20. https://trac.webkit.org/browser/trunk/Source/JavaScriptCore/ builtins/ArrayPrototype.js M E R G E S O R

    T N I T R O
  21. https://github.com/Microsoft/ChakraCore/blob/master/ lib/Common/DataStructures/QuickSort.h Q U I C K S O R

    T S O R T C H A K R A
  22. @koste4 JS Engine Sort Algorithm SpiderMonkey F I R E

    F O X Insertion Sort (for short arrays)
 Merge Sort V8 C H R O M E Insertion Sort (for short arrays)
 Quick Sort Nitro S A FA R I Merge Sort Chakra I N T E R N E T E X P L O R E R QuickSort
  23. @koste4 SORTING ALGORITHMS

  24. @koste4 STABILITY A stable sort is one in which equivalent

    elements retain their relative positions after sorting
  25. @koste4 Insertion Sort 3 Merge Sort Quick Sort 1 2

  26. @koste4 INSERTION SORT The array is searched sequentially and unsorted

    items are moved and inserted into a sorted sub-list kept within the same array.
  27. 27 1 function InsertionSort(arr) { 2 3 let len =

    arr.length, // number of items in the array 4 value, // the value currently being compared 5 i, // index into unsorted section 6 j; // index into sorted section 7 8 for(i = 1; i < len; i++) { 9 10 // store the current value because it may shift later 11 value = arr[i] 12 13 // Whenever the value in the sorted section is greater than the value 14 // in the unsorted section, shift all items in the sorted section over 15 // by one. This creates space in which to insert the value. 16 for (j = i - 1; j >= 0 && arr[j] > value; j--) { 17 arr[j+1] = arr[j] 18 } 19 arr[j+1] = value 20 } 21 22 return arr 23 24 }
  28. @koste4 10 LOC

  29. @koste4 DIVIDE & CONQUER Napoleonic tactics "Military genius" Divide the

    enemy in halves & surprise them individually 1 3 2 Conquer (attack) the enemy since it'll be reduced to half its size Concentrate resources in a single problem
  30. @koste4 MERGE SORT Divide the array into 2 subarrays each

    with n/2 elements 1 3 2 Conquer each subarray by sorting it. Unless the array is sufficiently small, use recursion to do this Combine the solutions to the subarrays by merging them into a single sorted array
  31. @koste4 MERGE SORT

  32. 32 1 function MergeSort(arr) { 2 3 let len =

    arr.length, // number of items in the array 4 middle, // middle of the array 5 left, // left side of the array 6 right // right side of the array 7 8 // Arrays with 0 or 1 elements don't need sorting 9 if (len < 2) { 10 return arr 11 } 12 13 middle = Math.floor(len/2) 14 15 left = arr.slice(0, middle) // left side, from 0 to the middle 16 right = arr.slice(middle) // right side, from the middle to the end 17 18 return merge(MergeSort(left), MergeSort(right)) 19 20 }
  33. 33 1 // Merges 2 sorted arrays 2 function merge(left,

    right) { 3 let result = [], 4 i = 0, 5 j = 0 6 7 while(i < left.length && j < right.length) { 8 9 // Elements in both arrays are compared against each other. 10 // Whichever element is smaller it's inserted in the results. 11 12 // Each time a value from an array is added, it’s 13 // corresponding index variable is incremented. 14 15 if(left[i] < right[j]) { 16 result.push(left[i++]) 17 } else { 18 result.push(right[j++]) 19 } 20 } 21 22 // As soon as one of the arrays has been finished, the 23 // remaining values are added to the end of the result array 24 25 return result.concat(left.slice(i)).concat(right.slice(j)) 26 27 }
  34. @koste4 23 LOC

  35. @koste4 QUICK SORT Find a pivot 1 3 2 Partition

    the array so that all items smaller than the pivot item are to the left and all items larger are to the right Sort the subarrays
  36. @koste4 QUICK SORT

  37. 37 1 // Find a "pivot" element in the array

    to compare all other 2 // elements against and then shift elements before or after 3 // pivot depending on their values 4 function QuickSort(arr, left = 0, right = arr.length - 1) { 5 let len = arr.length, 6 index 7 8 if(len > 1) { 9 10 index = partition(arr, left, right) 11 12 if(left < index - 1) { 13 QuickSort(arr, left, index - 1) 14 } 15 16 if(index < right) { 17 QuickSort(arr, index, right) 18 } 19 20 } 21 22 return arr 23 24 }
  38. 38 1 function partition(arr, left, right) { 2 let middle

    = Math.floor((right + left) / 2), 3 pivot = arr[middle], 4 i = left, // Start pointer at the first item in the array 5 j = right // Start pointer at the last item in the array 6 7 while(i <= j) { 8 // Move left pointer to the right until the value at the 9 // left is greater than the pivot value 10 while(arr[i] < pivot) { 11 i++ 12 } 13 14 // Move right pointer to the left until the value at the 15 // right is less than the pivot value 16 while(arr[j] > pivot) { 17 j-- 18 } 19 20 // If the left pointer is less than or equal to the 21 // right pointer, then swap values 22 if(i <= j) { 23 [arr[i], arr[j]] = [arr[j], arr[i]] // ES6 destructuring swap 24 i++ 25 j-- 26 } 27 } 28 29 return i 30 31 }
  39. @koste4 31 LOC

  40. 1 Array.prototype.InsertSort = function() { 2 /* your implementation here

    */ 3 } 4 5 Array.prototype.MergeSort = function() { 6 /* your implementation here */ 7 } 8 9 Array.prototype.QuickSort = function() { 10 /* your implementation here */ 11 } 12 13 myArray.InsertSort() 14 myArray.MergeSort() 15 myArray.QuickSort()
  41. @koste4 WHY SHOULD I CARE?

  42. @koste4 DESIGN STRATEGIES

  43. @koste4

  44. @koste4 $ git bisect start

  45. @koste4 STABILITY

  46. @koste4

  47. const people = [ { name: 'Faith Acet', age: 17

    }, { name: 'Armagan Amcalar', age: 42 }, { name: 'Yaprak Ayazoglu', age: 26 }, { name: 'Douglas Crockford', age: 26 }, { name: 'Varya Dubinina', age: 11 }, { name: 'Imad Elyafi', age: 26 }, { name: 'Sebastian Golasch', age: 26 }, { name: 'Diego González', age: 6 }, { name: 'Claudia Hernández', age: 26 }, { name: 'Asim Hussain', age: 26 }, { name: 'Georg Neis', age: 12 }, { name: 'Maxim Salnikov', age: 32 }, { name: 'Isa Silveria', age: 32 }, { name: 'André Staltz', age: 54 }, { name: 'Jennifer Voss', age: 11 }, ]
  48. people.sort((a,b) => { 
 return a.age - b.age }

  49. @koste4 V8

  50. [{ name: 'Diego González', age: 6 }, { name: 'Jennifer

    Voss', age: 11 }, { name: 'Varya Dubinina', age: 11 }, { name: 'Georg Neis', age: 12 }, { name: 'Faith Acet', age: 17 }, { name: 'Imad Elyafi', age: 26 }, { name: 'Sebastian Golasch', age: 26 }, { name: 'Douglas Crockford', age: 26 }, { name: 'Claudia Hernández', age: 26 }, { name: 'Yaprak Ayazoglu', age: 26 }, { name: 'Asim Hussain', age: 26 }, { name: 'Maxim Salnikov', age: 32 }, { name: 'Isa Silveira', age: 32 }, { name: 'Armagan Amcalar', age: 42 }, { name: 'André Staltz', age: 54 }]
  51. @koste4 NITRO

  52. [{ name: 'Diego González', age: 6 }, { name: 'Jennifer

    Voss', age: 11 }, { name: 'Varya Dubinina', age: 11 }, { name: 'Georg Neis', age: 12 }, { name: 'Faith Acet', age: 17 }, { name: 'Yaprak Ayazoglu', age: 26 }, { name: 'Douglas Crockford', age: 26 }, { name: 'Imad Elyafi', age: 26 }, { name: 'Sebastian Golasch', age: 26 }, { name: 'Claudia Hernández', age: 26 }, { name: 'Asim Hussain', age: 26 }, { name: 'Maxim Salnikov', age: 32 }, { name: 'Isa Silveira', age: 32 }, { name: 'Armagan Amcalar', age: 42 }, { name: 'André Staltz', age: 54 }]
  53. @koste4 PERFORMANCE

  54. 54 V 8 N I T R O

  55. @koste4 SELF-HOSTING Implementing parts of a language in that very

    language itself
  56. @koste4 All these array methods take a callback as an

    argument Arrays in JS have methods like , _ , and of course 
 forEach map reduce sort BUT, BUT, SLOW...
  57. @koste4 They iterate over the list and invoke the callback

    for every element Execution has to switch between compiled C++ and interpreted JS BUT, BUT, SLOW...
  58. @koste4 Context switch is expensive Staying in the same execution

    context and within the same language allows us to have additional nice things BUT, BUT, SLOW...
  59. @koste4 JS Engine Sort Algorithm Self-Host ? SpiderMonkey F I

    R E F O X Insertion Sort 
 (for short arrays)
 Merge Sort No V8 C H R O M E Insertion Sort 
 (for short arrays)
 Quick Sort Yes Nitro S A FA R I Merge Sort Yes Chakra I N T E R N E T E X P L O R E R QuickSort No
  60. @koste4 LET’S DO SOME 
 BENCHMARKING!

  61. @koste4 10 ELEMENTS

  62. @koste4 10O ELEMENTS

  63. @koste4 1,0O0 ELEMENTS

  64. @koste4 100,00O ELEMENTS

  65. @koste4 1,000,000 ELEMENTS

  66. None
  67. @koste4 1,000,000 ELEMENTS

  68. @koste4 10,000,000 ELEMENTS

  69. 69 Claudia’s Sorting Algorithms Certification ALL OF YOU SORTING ALGORITHMS

    IN JS AMSTERDAMJS 2018 01 JUN 2018 * Not a real certificate *
  70. None
  71. @koste4 MORE INFO... The Algorithm Design Manual by Steven S.

    Skiena Foundations of Algorithms by Richard Neapolitan & Kumarss Naimipour
  72. @koste4 https://www.youtube.com/watch?v=ROalU379l3U MORE INFO...

  73. @koste4 https://alistapart.com/article/what-i-talk-about-when-i-talk-about-sorting

  74. @koste4 Dank je!