on master help sign in
Merge pull request #593 from Xashili/arrayPerf
3fe77a6Evan Czaplicki
libraries/Native/Array.js+26−21
@@ -24,7 +24,6 @@ Elm.Native.Array.make = function(elm) {
24 // An empty array.
24 // An empty array.
25 var empty = { ctor:"_Array", height:0, table:new Array() };
25 var empty = { ctor:"_Array", height:0, table:new Array() };
26
26
27− // Gets the value at index i recursively.
28 function get(i, array) {
27 function get(i, array) {
29 if (i < 0 || i >= length(array)) {
28 if (i < 0 || i >= length(array)) {
30 throw new Error("Index " + i + " is out of range. Check the length of " +
29 throw new Error("Index " + i + " is out of range. Check the length of " +
@@ -34,31 +33,39 @@ Elm.Native.Array.make = function(elm) {
34 }
33 }
35
34
36 function unsafeGet(i, array) {
35 function unsafeGet(i, array) {
37− if (array.height == 0) {
36+ for (var x = array.height; x > 0; x--) {
38− return array.table[i];
37+ var slot = i >> (x * 5);
38+ if (slot > 0) {
39+ while (array.lengths[slot - 1] > i) { slot--; }
40+ i -= array.lengths[slot - 1];
39 }
41 }
40− var slot = getSlot(i, array);
42+ array = array.table[slot];
41− var offset = slot > 0 ? array.lengths[slot-1] : 0;
43+ }
42− return unsafeGet(i - offset, array.table[slot]);
44+ return array.table[i];
43 }
45 }
44
46
45 // Sets the value at the index i. Only the nodes leading to i will get
47 // Sets the value at the index i. Only the nodes leading to i will get
46 // copied and updated.
48 // copied and updated.
47− function set(i, item, a) {
49+ function set(i, item, array) {
48− if (length(a) <= i) {
50+ if (i < 0 || length(array) <= i) {
49− return a;
51+ return array;
50 }
52 }
51− var newA = nodeCopy(a);
53+ return unsafeSet(i, item, array);
52− newA.table = a.table.slice();
54+ }
53
55
56+ function unsafeSet(i, item, array) {
57+ array = nodeCopy(array);
58+
54− if (a.height == 0) {
59+ if (array.height == 0) {
55− newA.table[i] = item;
60+ array.table[i] = item;
56 } else {
61 } else {
57− var slot = getSlot(i, a);
62+ var slot = getSlot(i, array);
63+ if (slot > 0) {
58− var sub = slot > 0 ? a.lengths[slot-1] : 0;
64+ i -= array.lengths[slot - 1];
65+ }
59− newA.table[slot] = set(i - sub, item, a.table[slot]);
66+ array.table[slot] = unsafeSet(i, item, array.table[slot]);
60 }
67 }
61− return newA;
68+ return array;
62 }
69 }
63
70
64 function initialize(len, f) {
71 function initialize(len, f) {
@@ -533,10 +540,8 @@ Elm.Native.Array.make = function(elm) {
533 // Calculates in which slot of "table" the item probably is, then
540 // Calculates in which slot of "table" the item probably is, then
534 // find the exact slot via forward searching in "lengths". Returns the index.
541 // find the exact slot via forward searching in "lengths". Returns the index.
535 function getSlot(i, a) {
542 function getSlot(i, a) {
536− var slot = Math.floor(i / (Math.pow(M, a.height)));
543+ var slot = i >> (5 * a.height);
537− while (a.lengths[slot] <= i) {
544+ while (a.lengths[slot - 1] > i) { slot--; }
538− slot++
539− }
540 return slot;
545 return slot;
541 }
546 }
542
547