2016-04-09 24 views
1

Ich versuche, ein Array der Größe 2^32 = 4294967296 zu erstellen, weil ich versuche, alle Primzahlen bis 2^32 durch Ausführen des Siebalgorithmus zu bekommen. Aber jede Operation in diesem Array bekomme ich den folgenden Fehler:Javascript Vergrößern maximale Array-Größe

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory

Abort trap: 6

Was kann ich in der obigen Situation tun?

+0

Verwendung ein Objekt statt spärlich Arrays. – dandavis

+7

Das sind 4 Milliarden Elemente. Warum brauchen Sie ein Array dieser Größe? – Andy

+1

Wie auch immer, versuchen Sie stattdessen 4294967295 ((2^32) - 1). – Andy

Antwort

1

Arrays können nicht so groß sein, ist die maximale Länge 2 -1. Nach ECMAScript spec,

Every Array object has a length property whose value is always a nonnegative integer less than 232.

A String property name P is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 232−1.

+0

Denken Sie, sein Tag ist 'node.js' und die Geschichte ist anders als. – skobaljic

+0

@skobaljic Node.js ist eine ECMAScript-Implementierung. – Oriol

+0

Schätze, du weißt es besser. Soweit ich weiß, ist es nur auf Javascript Engine gebaut und Sie können es auf viele Arten, weit anders als Javascript im Browser erweitern. – skobaljic

6

Ein Array von 2^32 Elementen ist im Grunde 4 GB * size of an element, also gibt es hohe Chancen, dass es nicht in den Speicher passt.

Der Fehler, den Sie erhalten, ist genau das: Der Zuordner kann nicht genügend Speicherplatz reservieren. Vielleicht möchten Sie eine andere Lösung in Betracht ziehen, als ein Array mit mehreren Gigabyte zuzuweisen. Mit ein wenig mehr Details über das, was Sie erreichen möchten, könnte Ihnen helfen, Sie auf den richtigen Weg zu bringen! :)

+0

Ich versuche alle Primzahlen bis 2^32 zu bekommen und versuche den Siebalgorithmus auszuführen. –

3

Für node.js einfach big-array installieren.

A resizable array using non-sequential block memory allocation. Growing or shrinking the array does not require reallocation of the entire array. Useful when you need to track a few trillion data points.

1

Für einen Siebalgorithmus, brauchen Sie nur ein Bit für jede Zahl zu testen ...

Suchen Sie nach einer bitset Implementierung (https://github.com/tdegrunt/bitset zum Beispiel). Dieser wird dynamisch wachsen, wenn Sie Bits darin setzen. Sie können Bits setzen und erhalten, und jedes Bit wird Ihnen sagen, ob n eine Primzahl ist.

Allerdings empfehle ich Sie mit max 100 testen, nicht 2^32 ... weil es langsam sein ...

Eigentlich bitset Pausen zwischen 10M und 100M auf meinem Mac. Ich schätze, sie verwenden kein Byte-Array.

In Kaffee-Skript, weil es weniger ausführlich ist ...

Bitset = require 'bitset' 

sieve = (maxSize)=> 

    mark = (bitset)-> 
     markMultiplesOf = (n)-> 
      bitset.set(n*each) for each in [2..(maxSize/n)] 

     markMultiplesOf each for each in [2..(maxSize/2)] when bitset.get(each) is false 

    showPrimes = (bitset)-> 
     console.log each for each in [0..(bitset.length())] when bitset.get(each) is false 

    timestamp = Date.now() 

    bitset = new Bitset(maxSize) 
    mark bitset, maxSize 

    console.log "took #{Date.now() - timestamp} ms" 
    showPrimes(bitset) 

sieve(10000000) # takes < 4s