452 Stimmen

Wie kann man die Größe eines JavaScript-Objekts ermitteln?

Ich möchte die von einem JavaScript-Objekt belegte Größe wissen.

Nehmen Sie die folgende Funktion:

function Marks(){
  this.maxMarks = 100;
}

function Student(){
  this.firstName = "firstName";
  this.lastName = "lastName";
  this.marks = new Marks();
}

Jetzt instanziere ich die student :

var stud = new Student();

so dass ich Dinge tun kann wie

stud.firstName = "new Firstname";

alert(stud.firstName);

stud.marks.maxMarks = 200;

usw.

Nun, die stud Objekt wird eine gewisse Größe im Speicher belegen. Es enthält einige Daten und weitere Objekte.

Wie kann ich herausfinden, wie viel Speicherplatz die stud Objekt einnimmt? Etwas wie ein sizeof() in JavaScript? Es wäre wirklich toll, wenn ich es mit einem einzigen Funktionsaufruf herausfinden könnte, z.B. sizeof(stud) .

Ich habe das Internet monatelang durchsucht und konnte es nicht finden (ich habe in einigen Foren gefragt - keine Antworten).

2voto

Boris Rayskiy Punkte 19
function sizeOf(parent_data, size)
{
    for (var prop in parent_data)
    {
        let value = parent_data[prop];

        if (typeof value === 'boolean')
        {
            size += 4;
        }
        else if (typeof value === 'string')
        {
            size += value.length * 2;
        }
        else if (typeof value === 'number')
        {
             size += 8;
        }
        else
        {      
            let oldSize = size;
            size += sizeOf(value, oldSize) - oldSize;
        }
    }

    return size;
}

function roughSizeOfObject(object)
{   
    let size = 0;
    for each (let prop in object)
    {    
        size += sizeOf(prop, 0);
    } // for..
    return size;
}

1voto

Alex M Punkte 31

Wenn Sie die ungefähre Größe von Objekten programmatisch überprüfen möchten, können Sie auch diese Bibliothek verwenden http://code.stephenmorley.org/javascript/finding-the-memory-usage-of-objects/ die ich für die Größe der Objekte verwenden konnte.

Andernfalls empfehle ich, den Chrome/Firefox Heap Profiler zu verwenden.

1voto

matanster Punkte 14503

Ich verwende die Chrome-Entwicklungstools". Registerkarte Zeitleiste immer größere Mengen von Objekten instanziieren und auf diese Weise gute Schätzungen erhalten. Sie können eine HTML-Datei wie die folgende als Vorlage verwenden und sie so abändern, dass sie die Eigenschaften Ihrer Objekte besser simuliert (Anzahl und Arten von Eigenschaften usw.). Sie sollten vor und nach einem Durchlauf auf das Papierkorbsymbol am unteren Rand der Registerkarte Entwicklungswerkzeuge klicken.

<html>
<script>
var size = 1000*100
window.onload = function() {
  document.getElementById("quantifier").value = size
}

function scaffold()
{
  console.log("processing Scaffold...");
  a = new Array
}

function start()
{
  size = document.getElementById("quantifier").value
  console.log("Starting... quantifier is " + size);
  console.log("starting test")
  for (i=0; i<size; i++){
    a[i]={"some" : "thing"}
  }
  console.log("done...")
}

function tearDown()
{
  console.log("processing teardown");
  a.length=0
}

</script>
<body>
    <span style="color:green;">Quantifier:</span>
    <input id="quantifier" style="color:green;" type="text"></input>
    <button onclick="scaffold()">Scaffold</button>
    <button onclick="start()">Start</button>
    <button onclick="tearDown()">Clean</button>
    <br/>
</body>
</html>

Die Instanziierung von 2 Millionen Objekten mit jeweils nur einer Eigenschaft (wie in diesem Code oben) führt auf meinem Chromium derzeit zu einer groben Berechnung von 50 Byte pro Objekt. Ändern Sie den Code, um eine zufällige Zeichenfolge pro Objekt zu erstellen, fügt etwa 30 Byte pro Objekt usw. Hoffentlich hilft das.

1voto

OXiGEN Punkte 1443

Aufbauend auf der bereits kompakten Lösung von @Dan hier eine in sich geschlossene Funktionsversion der Lösung. Die Variablennamen sind auf einzelne Buchstaben reduziert für diejenigen, die es auf Kosten des Kontexts so kompakt wie möglich haben wollen.

const ns = {};
ns.sizeof = function(v) {
  let f = ns.sizeof, //this needs to match the name of the function itself, since arguments.callee.name is defunct
    o = {
      "undefined": () => 0,
      "boolean": () => 4,
      "number": () => 8,
      "string": i => 2 * i.length,
      "object": i => !i ? 0 : Object
        .keys(i)
        .reduce((t, k) => f(k) + f(i[k]) + t, 0)
    };
  return o[typeof v](v);
};

ns.undef;
ns.bool = true;
ns.num = 1;
ns.string = "Hello";
ns.obj = {
  first_name: 'John',
  last_name: 'Doe',
  born: new Date(1980, 1, 1),
  favorite_foods: ['Pizza', 'Salad', 'Indian', 'Sushi'],
  can_juggle: true
};

console.log(ns.sizeof(ns.undef));
console.log(ns.sizeof(ns.bool));
console.log(ns.sizeof(ns.num));
console.log(ns.sizeof(ns.string));
console.log(ns.sizeof(ns.obj));
console.log(ns.sizeof(ns.obj.favorite_foods));

1voto

Stephen Quan Punkte 16456

Ich hatte Probleme mit der obigen Antwort mit einer ArrayBuffer . Nach der Überprüfung der Dokumentation, fand ich, dass ArrayBuffer hat eine byteLength die mir genau sagt, was ich brauche, also:

function sizeOf(data)
{
    if (typeof(data) === 'object')
    {
        if (data instanceof ArrayBuffer)
        {
            return data.byteLength;
        }
        // other objects goes here
    }
    // non-object cases goes here
}

console.log(sizeOf(new ArrayBuffer(15))); // 15

Referenz:

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X