Are Javascript arrays sparse?

后端 未结 7 2291
情书的邮戳
情书的邮戳 2020-11-22 08:12

That is, if I use the current time as an index into the array:

array[Date.getTime()] = value;

will the interpreter instantiate all the elem

7条回答
  •  不知归路
    2020-11-22 08:39

    Sparseness (or denseness) can be confirmed empirically for NodeJS with the non-standard process.memoryUsage().

    Sometimes node is clever enough to keep the array sparse:

    Welcome to Node.js v12.15.0.
    Type ".help" for more information.
    > console.log(`The script is using approximately ${Math.round(process.memoryUsage().heapUsed / 1024 / 1024 * 100) / 100} MB`)
    The script is using approximately 3.07 MB
    undefined
    > array = []
    []
    > array[2**24] = 2**24
    16777216
    > array
    [ <16777216 empty items>, 16777216 ]
    > console.log(`The script is using approximately ${Math.round(process.memoryUsage().heapUsed / 1024 / 1024 * 100) / 100} MB`)
    The script is using approximately 2.8 MB
    undefined
    

    Sometimes node chooses to make it dense (this behavior might well be optimized in future):

    > otherArray = Array(2**24)
    [ <16777216 empty items> ]
    > console.log(`The script is using approximately ${Math.round(process.memoryUsage().heapUsed / 1024 / 1024 * 100) / 100} MB`)
    The script is using approximately 130.57 MB
    undefined
    

    Then sparse again:

    > yetAnotherArray = Array(2**32-1)
    [ <4294967295 empty items> ]
    > console.log(`The script is using approximately ${Math.round(process.memoryUsage().heapUsed / 1024 / 1024 * 100) / 100} MB`)
    The script is using approximately 130.68 MB
    undefined
    

    So perhaps using a dense array to get a feel for the original AIX kernel bug might need to be forced with a range-alike:

    > denseArray = [...Array(2**24).keys()]
    [
       0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,
      12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
      24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
      36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
      48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
      60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
      72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
      84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
      96, 97, 98, 99,
      ... 16777116 more items
    ]
    > console.log(`The script is using approximately ${Math.round(process.memoryUsage().heapUsed / 1024 / 1024 * 100) / 100} MB`);
    The script is using approximately 819.94 MB
    undefined
    

    Because why not make it fall over?

    > tooDenseArray = [...Array(2**32-1).keys()]
    
    <--- Last few GCs --->
    
    [60109:0x1028ca000]   171407 ms: Scavenge 1072.7 (1090.0) -> 1056.7 (1090.0) MB, 0.2 / 0.0 ms  (average mu = 0.968, current mu = 0.832) allocation failure 
    [60109:0x1028ca000]   171420 ms: Scavenge 1072.7 (1090.0) -> 1056.7 (1090.0) MB, 0.2 / 0.0 ms  (average mu = 0.968, current mu = 0.832) allocation failure 
    [60109:0x1028ca000]   171434 ms: Scavenge 1072.7 (1090.0) -> 1056.7 (1090.0) MB, 0.2 / 0.0 ms  (average mu = 0.968, current mu = 0.832) allocation failure 
    
    
    <--- JS stacktrace --->
    
    ==== JS stack trace =========================================
    
        0: ExitFrame [pc: 0x100931399]
        1: StubFrame [pc: 0x1008ee227]
        2: StubFrame [pc: 0x100996051]
    Security context: 0x1043830808a1 
        3: /* anonymous */ [0x1043830b6919] [repl:1] [bytecode=0x1043830b6841 offset=28](this=0x104306fc2261 )
        4: InternalFrame [pc: 0x1008aefdd]
        5: EntryFrame [pc: 0x1008aedb8]
        6: builtin exit frame: runInThisContext(this=0x104387b8cac1 

提交回复
热议问题