$30 off During Our Annual Pro Sale. View Details »

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!

Claudia Hernández

June 01, 2018
Tweet

More Decks by Claudia Hernández

Other Decks in Technology

Transcript

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

    View Slide

  2. CS 101

    Intro to computational
    complexity:
    The Sorting Problem

    View Slide

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

    View Slide

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

    DANCE
    ,
    HAVE IN
    COMMON?

    View Slide

  5. @koste4
    COMPUTATIONAL

    COMPLEXITY
    Study of all the possible
    algorithms that can solve a
    problem

    View Slide

  6. @koste4
    Algorithm that sorts elements of
    a list according to a certain
    order. The most commonly used
    orders are numerical &
    lexicographical
    SORTING
    ALGORTHIM

    View Slide

  7. @koste4
    ARRAY SORT IN JS
    #
    1 myArray = [33, 2, 98, 25, 4]
    2 myArray.sort() // [ 2, 25, 33, 4, 98 ]

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  11. @koste4
    ARRAY SORT IN JS
    #
    1 // [ 2, 25, 33, 4, 98 ]

    View Slide

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

    View Slide

  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 ]

    View Slide

  14. @koste4
    ¿HAVE YOU EVER
    WHICH
    WONDERED
    ALGORITHIM IS USED
    IN JAVASCRIPT’S
    NATIVE SORT FUNCTION ?
    JAVASCRIPT

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  23. @koste4
    SORTING
    ALGORITHMS

    View Slide

  24. @koste4
    STABILITY
    A stable sort is one in which
    equivalent elements retain
    their relative positions after
    sorting

    View Slide

  25. @koste4
    Insertion Sort
    3
    Merge Sort
    Quick Sort
    1
    2

    View Slide

  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.

    View Slide

  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 }

    View Slide

  28. @koste4
    10 LOC

    View Slide

  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

    View Slide

  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

    View Slide

  31. @koste4
    MERGE SORT

    View Slide

  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 }

    View Slide

  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 }

    View Slide

  34. @koste4
    23 LOC

    View Slide

  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

    View Slide

  36. @koste4
    QUICK SORT

    View Slide

  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 }

    View Slide

  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 }

    View Slide

  39. @koste4
    31 LOC

    View Slide

  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()

    View Slide

  41. @koste4
    WHY
    SHOULD I
    CARE?

    View Slide

  42. @koste4
    DESIGN
    STRATEGIES

    View Slide

  43. @koste4

    View Slide

  44. @koste4
    $ git bisect start

    View Slide

  45. @koste4
    STABILITY

    View Slide

  46. @koste4

    View Slide

  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 },
    ]

    View Slide

  48. people.sort((a,b) => { 

    return a.age - b.age
    }

    View Slide

  49. @koste4
    V8

    View Slide

  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 }]

    View Slide

  51. @koste4
    NITRO

    View Slide

  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 }]

    View Slide

  53. @koste4
    PERFORMANCE

    View Slide

  54. 54
    V 8 N I T R O

    View Slide

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

    View Slide

  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...

    View Slide

  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...

    View Slide

  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...

    View Slide

  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

    View Slide

  60. @koste4
    LET’S DO SOME 

    BENCHMARKING!

    View Slide

  61. @koste4
    10 ELEMENTS

    View Slide

  62. @koste4
    10O ELEMENTS

    View Slide

  63. @koste4
    1,0O0 ELEMENTS

    View Slide

  64. @koste4
    100,00O ELEMENTS

    View Slide

  65. @koste4
    1,000,000 ELEMENTS

    View Slide

  66. View Slide

  67. @koste4
    1,000,000 ELEMENTS

    View Slide

  68. @koste4
    10,000,000 ELEMENTS

    View Slide

  69. 69
    Claudia’s Sorting
    Algorithms
    Certification
    ALL OF YOU
    SORTING ALGORITHMS IN JS
    AMSTERDAMJS 2018
    01 JUN 2018
    * Not a real certificate
    *

    View Slide

  70. View Slide

  71. @koste4
    MORE INFO...
    The Algorithm Design Manual
    by Steven S. Skiena
    Foundations of Algorithms
    by Richard Neapolitan &
    Kumarss Naimipour

    View Slide

  72. @koste4
    https://www.youtube.com/watch?v=ROalU379l3U
    MORE INFO...

    View Slide

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

    View Slide

  74. @koste4
    Dank je!

    View Slide