Bagaimana cara mendapatkan ukuran objek JavaScript?

297

Saya ingin tahu ukuran yang ditempati oleh objek JavaScript.

Ambil fungsi berikut:

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

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

Sekarang saya instantiate student:

var stud = new Student();

sehingga saya bisa melakukan hal-hal seperti

stud.firstName = "new Firstname";

alert(stud.firstName);

stud.marks.maxMarks = 200;

dll.

Sekarang, studobjek akan menempati beberapa ukuran dalam memori. Ini memiliki beberapa data dan lebih banyak objek.

Bagaimana cara mengetahui berapa banyak memori yang studditempati objek? Sesuatu seperti sizeof()di JavaScript? Akan sangat luar biasa jika saya bisa mengetahuinya dalam satu panggilan fungsi saja sizeof(stud).

Saya telah mencari di Internet selama berbulan-bulan - tidak dapat menemukannya (diminta di beberapa forum - tidak ada balasan).

pengguna4642212
sumber
41
Ada (akan muncul) banyak alasan mengapa saya perlu menemukan ukuran suatu objek dalam JavaScript. Saya baru mengenal JavaScript, jadi saya tidak mengikuti praktik terbaik. Saya masih mempelajarinya. Saya telah mengembangkan ekstensi firefox yang saya yakin menggunakan lebih banyak memori daripada yang seharusnya. Saya sedang mengerjakan beberapa cara untuk (mudah-mudahan) mengurangi penggunaan memori .. saya berbicara tentang ribuan contoh banyak objek per tab, jadi memori itu penting! Masalahnya, saya ingin tahu apakah upaya pengurangan memori saya benar-benar membantu mengurangi memori .. dan seberapa banyak.
1
Jika Anda telah membangun ekstensi FF, saya sarankan Anda untuk menyelidiki di tingkat bahasa yang lebih tinggi dari JS - lihat apa dampaknya pada FF itu sendiri.
annakata
2
Bahasa tingkat lebih tinggi dari JS? apa yang akan terjadi dalam kasus ini?
24
Itu bukan ukuran yang penting. Begitulah cara Anda menggunakannya. PS: Benar-benar pejantan!
Thomas Eding
13
@SpencerRuport Alasan nomor satu untuk mengetahui ukuran objek adalah untuk aplikasi html5 yang mampu offline di mana Anda terkadang memiliki ruang penyimpanan terbatas (5-10Mb dapat dimakan dengan cepat untuk aplikasi intensif data).
David

Jawaban:

181

Saya telah memfaktorkan ulang kode dalam jawaban asli saya . Saya telah menghapus rekursi dan menghapus keberadaan yang ada di atas.

function roughSizeOfObject( object ) {

    var objectList = [];
    var stack = [ object ];
    var bytes = 0;

    while ( stack.length ) {
        var value = stack.pop();

        if ( typeof value === 'boolean' ) {
            bytes += 4;
        }
        else if ( typeof value === 'string' ) {
            bytes += value.length * 2;
        }
        else if ( typeof value === 'number' ) {
            bytes += 8;
        }
        else if
        (
            typeof value === 'object'
            && objectList.indexOf( value ) === -1
        )
        {
            objectList.push( value );

            for( var i in value ) {
                stack.push( value[ i ] );
            }
        }
    }
    return bytes;
}
thomas-peter
sumber
35
Anda mungkin ingin memikirkan kunci objek juga
zupa
8
Siapa pun yang mendarat di sini mencari tipe terkecil untuk keperluan false / true, tampaknya tidak terdefinisi / null.
zupa
3
"よんもじ".lengthadalah 4 dalam Javascript, tetapi apakah Anda yakin itu 8 byte, karena kode Anda mengembalikannya?
syockit
8
Ya. Karakter dalam JavaScript disimpan sesuai dengan Spesifikasi ECMA-262 3rd Edition - bclary.com/2004/11/07/#a-4.3.16
thomas-peter
4
Fungsi ini tidak menghitung referensi yang tersembunyi di penutupan. Misalnya var a={n:1}; var b={a:function(){return a}}; roughSizeOfObject(b)- di sini bmemiliki referensi a, tetapi roughSizeOfObject()kembali 0.
Roman Pominov
117

Google Chrome Heap Profiler memungkinkan Anda memeriksa penggunaan memori objek.

Anda harus dapat menemukan objek dalam jejak yang bisa rumit. Jika Anda menyematkan objek ke Window global, cukup mudah untuk menemukan dari mode listing "Containment".

Pada tangkapan layar terlampir, saya membuat objek yang disebut "testObj" di jendela. Saya kemudian terletak di profiler (setelah membuat rekaman) dan itu menunjukkan ukuran penuh objek dan semua yang ada di bawah "ukuran dipertahankan".

Rincian lebih lanjut tentang kerusakan memori .

Profiler Chrome

Pada tangkapan layar di atas, objek menunjukkan ukuran tetap 60. Saya percaya unit ini byte di sini.

Guy Bedford
sumber
13
Jawaban ini menyelesaikan masalah saya bersama dengan: developers.google.com/chrome-developer-tools/docs/… . Tip cepat: ambil Snapshot Tumpukan cepat, jalankan tugas yang Anda curigai bocor, ambil Snapshot Tumpukan cepat baru dan pilih comparisontampilan di bagian bawah. Itu memperjelas objek apa yang dibuat antara kedua snapshot.
Johnride
1
Ini mungkin solusi terbersih.
Luca Steeb
Perbandingan, disebutkan oleh @Johnride, sekarang menjadi menu pull-down di bagian atas.
frandroid
Shallow sizetampaknya 40 untuk keduanya { a:"55c2067aee27593c03b7acbe", b:"55c2067aee27593c03b7acbe", c:null, d:undefined }dan { c:null, d:undefined }objek. Apakah itu oke?
efkan
1
Anda dapat menggunakan Google Chrome Heap Profiler dari node juga. Jika Anda memiliki simpul v8 atau lebih, mulai dengan node --inspectdan di Chrome masukkan about:inspectdi bilah URL dan cari untuk membuka pengawas Node. Buat objek Anda di node CLI dan kemudian ambil snapshot tumpukan.
Gregor
74

Saya baru saja menulis ini untuk memecahkan masalah yang serupa. Itu tidak persis melakukan apa yang Anda cari, yaitu tidak memperhitungkan bagaimana penerjemah menyimpan objek.

Tapi, jika Anda menggunakan V8, itu akan memberi Anda perkiraan yang cukup ok karena prototipe yang mengagumkan dan kelas tersembunyi menjilat sebagian besar overhead.

function roughSizeOfObject( object ) {

    var objectList = [];

    var recurse = function( value )
    {
        var bytes = 0;

        if ( typeof value === 'boolean' ) {
            bytes = 4;
        }
        else if ( typeof value === 'string' ) {
            bytes = value.length * 2;
        }
        else if ( typeof value === 'number' ) {
            bytes = 8;
        }
        else if
        (
            typeof value === 'object'
            && objectList.indexOf( value ) === -1
        )
        {
            objectList[ objectList.length ] = value;

            for( i in value ) {
                bytes+= 8; // an assumed existence overhead
                bytes+= recurse( value[i] )
            }
        }

        return bytes;
    }

    return recurse( object );
}
thomas-peter
sumber
1
@Liangliang Zheng - titik bagus ulang tak terbatas, terima kasih. Semoga Anda tidak keberatan jika saya manggung ulang sedikit dan memperbarui milik saya setelah bekerja (?)
thomas-peter
Saya akan menguji bench ini malam ini dengan node.js dan mendapatkan beberapa koefisien yang lebih baik di tempat.
thomas-peter
Baris 'bytes + = recurse (value [i])', menimbulkan kesalahan pada FF 14.01 saya: NS_ERROR_FAILURE: Komponen mengembalikan kode kegagalan: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMHTMLInputElement.selectionStart]. Di salah satu Objek saya, jika saya mencoba yang lain, itu tidak, mungkin bug browser, atau kode tidak berfungsi untuk setiap objek (yang tidak berfungsi berisi fungsi, yang berfungsi tidak ' t)
TrySpace
1
Dari satu Tom ke yang lain, ini sangat berguna sebagai indikator kasar di mana saya perlu memotong pinggang objek saya. Jadi, apakah Nona Anda mengetahui tentang perselingkuhan Anda dengan Javascript? Dia nyonya pemeliharaan yang tinggi.
Tom W Hall
4
Ini PHP (tegukan) yang harus saya perhatikan - saya berhenti mencintainya sejak lama, tetapi dia membayar tagihan. Bagaimanapun, terima kasih Tom, umpan balik yang disukai jauh lebih baik daripada poin reputasi.
thomas-peter
55

Kadang-kadang saya menggunakan ini untuk menandai objek yang sangat besar yang mungkin pergi ke klien dari server. Itu tidak mewakili jejak memori. Itu hanya memberi Anda kira-kira berapa biaya untuk mengirimnya, atau menyimpannya.

Juga perhatikan, lambat, hanya dev. Tetapi untuk mendapatkan jawaban kasar dengan satu baris kode itu bermanfaat bagi saya.

roughObjSize = JSON.stringify(bigObject).length;
zstew
sumber
2
Dari pengujian saya, metode ini jauh lebih cepat daripada objek-ukuran case karena tidak memiliki panggilan _.isObject () lambat dari lodash. Selain itu ukuran yang dikembalikan cukup sebanding untuk perkiraan kasar. Gist gist.github.com/owenallenaz/ff77fc98081708146495 .
Nucleon
3
Sayang sekali rusak ketika benda terlalu besar . :(
cregox
5
Tidak dapat digunakan dengan struktur melingkar VM1409:1 Uncaught TypeError: Converting circular structure to JSON:( masih berguna
givanse
ini bukan ukuran biner dalam byte tetapi mudah digunakan untuk mendapatkan ukuran perkiraan
datdinhquoc
Ini cukup bagus jika 1) Anda hanya perlu perkiraan rata-rata 2) Anda tahu Anda tidak memiliki referensi melingkar 3) Anda dapat menghilangkan nilai besar dan mengacaukannya secara terpisah. Semua ini benar dalam kasus saya sehingga berfungsi dengan sempurna, saya hanya memiliki satu string besar di satu tempat yang saya hanya dapat mengukur panjangnya.
OZZIE
45

Inilah solusi yang sedikit lebih ringkas untuk masalah ini:

const typeSizes = {
  "undefined": () => 0,
  "boolean": () => 4,
  "number": () => 8,
  "string": item => 2 * item.length,
  "object": item => !item ? 0 : Object
    .keys(item)
    .reduce((total, key) => sizeOf(key) + sizeOf(item[key]) + total, 0)
};

const sizeOf = value => typeSizes[typeof value](value);
Dan
sumber
3
jadi ini ukuran dalam KB? atau bit?
vincent thorpe
2
@ vincent-thorpe Ada dalam bytes.
Dan
3
Skrip yang bagus, perlu modifikasi untuk referensi siklik.
Jim Pedid
1
Saya baru saja menguji algoritme Anda pada sejumlah besar data dalam proses simpul, ini melaporkan 13GB, tetapi simpul mengkonsumsi 22GB, ada ide tentang dari mana perbedaan itu berasal? Tidak ada yang lebih dalam memori.
Josu Goñi
3
@ JosuGoñi, mereka tidak menghitung berapa banyak objek itu sendiri, hanya nilainya. Semua objek mengambil lebih banyak ruang dari sekadar nilainya, jika typeof ...tidak , tidak akan berhasil.
Alexis Wilke
42

Ada modul NPM untuk mendapatkan ukuran objek , Anda dapat menginstalnyanpm install object-sizeof

  var sizeof = require('object-sizeof');

  // 2B per character, 6 chars total => 12B
  console.log(sizeof({abc: 'def'}));

  // 8B for Number => 8B
  console.log(sizeof(12345));

  var param = { 
    'a': 1, 
    'b': 2, 
    'c': {
      'd': 4
    }
  };
  // 4 one two-bytes char strings and 3 eighth-bytes numbers => 32B
  console.log(sizeof(param));
Andrei Karpushonak
sumber
sizeof (Tanggal baru ()) === 0 dan sizeof ({}) === 0. Apakah itu dimaksudkan?
Philipp Claßen
1
@ PhilippClaßen Jelas sekali. Kedua objek tidak memiliki properti.
Robert
18

Ini adalah metode hacky, tetapi saya mencobanya dua kali dengan angka yang berbeda dan tampaknya konsisten.

Yang dapat Anda lakukan adalah mencoba dan mengalokasikan sejumlah besar objek, seperti satu atau dua juta objek dari jenis yang Anda inginkan. Letakkan objek dalam array untuk mencegah pengumpul sampah melepaskannya (perhatikan bahwa ini akan menambah sedikit overhead memori karena array, tetapi saya harap ini tidak masalah dan selain itu jika Anda akan khawatir tentang objek yang ada di memori , Anda menyimpannya di suatu tempat). Tambahkan lansiran sebelum dan sesudah alokasi dan di setiap lansiran periksa berapa banyak memori yang diambil oleh proses Firefox. Sebelum Anda membuka halaman dengan tes, pastikan Anda memiliki contoh Firefox baru. Buka halaman, catat penggunaan memori setelah peringatan "sebelum" ditampilkan. Tutup peringatan, tunggu memori dialokasikan. Kurangi memori baru dari yang lebih lama dan bagi dengan jumlah alokasi.

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

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

var manyObjects = new Array();
alert('before');
for (var i=0; i<2000000; i++)
    manyObjects[i] = new Student();
alert('after');

Saya mencoba ini di komputer saya dan proses memiliki memori 48352K ketika peringatan "sebelum" ditampilkan. Setelah alokasi, Firefox memiliki memori 440236K. Untuk alokasi 2 juta, ini adalah sekitar 200 byte untuk setiap objek.

Saya mencobanya lagi dengan alokasi 1 juta dan hasilnya serupa: 196 byte per objek (saya kira data tambahan dalam 2mill digunakan untuk Array).

Jadi, inilah metode hacky yang mungkin bisa membantu Anda. JavaScript tidak menyediakan metode "sizeof" karena suatu alasan: setiap implementasi JavaScript berbeda. Di Google Chrome misalnya, halaman yang sama menggunakan sekitar 66 byte untuk setiap objek (setidaknya dilihat dari task manager).

Sektor Buruk
sumber
Hei .. terima kasih untuk tekniknya. Saya mengalami itu karena rencana B memetikan tidak ada cara langsung di sana untuk mengukur penggunaan memori.
4
Setiap implementasi C dan C ++ juga berbeda. ;) Ukuran tipe data dalam C atau C ++ spesifik untuk implementasi. Saya tidak melihat alasan JavaScript tidak dapat mendukung operator seperti itu, meskipun tidak akan melayani tujuan yang sama atau memiliki arti yang sama seperti di C atau C ++ (yang merupakan bahasa tingkat rendah dan mengukur ukuran sebenarnya dari suatu fixed- tipe data ukuran pada waktu kompilasi yang bertentangan dengan ukuran variabel objek JavaScript dinamis saat run-time).
bambams
12

Maaf saya tidak bisa berkomentar, jadi saya hanya melanjutkan pekerjaan dari tomwrong. Versi yang disempurnakan ini tidak akan menghitung objek lebih dari sekali, sehingga tidak ada loop tanpa batas. Plus, saya rasa kunci dari suatu objek juga harus dihitung, kira-kira.

function roughSizeOfObject( value, level ) {
    if(level == undefined) level = 0;
    var bytes = 0;

    if ( typeof value === 'boolean' ) {
        bytes = 4;
    }
    else if ( typeof value === 'string' ) {
        bytes = value.length * 2;
    }
    else if ( typeof value === 'number' ) {
        bytes = 8;
    }
    else if ( typeof value === 'object' ) {
        if(value['__visited__']) return 0;
        value['__visited__'] = 1;
        for( i in value ) {
            bytes += i.length * 2;
            bytes+= 8; // an assumed existence overhead
            bytes+= roughSizeOfObject( value[i], 1 )
        }
    }

    if(level == 0){
        clear__visited__(value);
    }
    return bytes;
}

function clear__visited__(value){
    if(typeof value == 'object'){
        delete value['__visited__'];
        for(var i in value){
            clear__visited__(value[i]);
        }
    }
}

roughSizeOfObject(a);
Liangliang Zheng
sumber
Saya pikir ini lebih akurat karena menghitung kunci, meskipun menghitung kunci '__visited__'
Sam Hasler
Memeriksa typeof value === 'object'tidak cukup dan Anda akan memiliki pengecualian jika nilainya null.
floribon
Ini sangat cepat untuk objek saya (yang saya cukup yakin memiliki cara lebih dari 5MB), dibandingkan dengan salah satu jawaban ditipu @ tomwrong. Itu juga lebih akurat (seperti yang dikatakan 3mb atau lebih) tetapi masih terlalu jauh dari kenyataan. Adakah petunjuk tentang apa yang mungkin tidak diperhitungkan?
cregox
Tidak bekerja untuk saya. Objek levelberisi data tetapi roughSizeOfObject(level)mengembalikan nol. (Level variabel saya tidak harus bingung dengan argumen Anda, tentu saja. Saya tidak berpikir bahwa variabel shadowing dapat menyebabkan masalah di sini, dan juga ketika saya mengganti nama 'level' dalam skrip Anda, saya mendapatkan hasil yang sama.) Screenshot : snipboard.io/G7E5yj.jpg
Luc
11

Memiliki masalah yang sama. Saya mencari di Google dan saya ingin berbagi dengan komunitas stackoverflow solusi ini.

Penting :

Saya menggunakan fungsi yang dibagikan oleh Yan Qing di github https://gist.github.com/zensh/4975495

function memorySizeOf(obj) {
    var bytes = 0;

    function sizeOf(obj) {
        if(obj !== null && obj !== undefined) {
            switch(typeof obj) {
            case 'number':
                bytes += 8;
                break;
            case 'string':
                bytes += obj.length * 2;
                break;
            case 'boolean':
                bytes += 4;
                break;
            case 'object':
                var objClass = Object.prototype.toString.call(obj).slice(8, -1);
                if(objClass === 'Object' || objClass === 'Array') {
                    for(var key in obj) {
                        if(!obj.hasOwnProperty(key)) continue;
                        sizeOf(obj[key]);
                    }
                } else bytes += obj.toString().length * 2;
                break;
            }
        }
        return bytes;
    };

    function formatByteSize(bytes) {
        if(bytes < 1024) return bytes + " bytes";
        else if(bytes < 1048576) return(bytes / 1024).toFixed(3) + " KiB";
        else if(bytes < 1073741824) return(bytes / 1048576).toFixed(3) + " MiB";
        else return(bytes / 1073741824).toFixed(3) + " GiB";
    };

    return formatByteSize(sizeOf(obj));
};


var sizeOfStudentObject = memorySizeOf({Student: {firstName: 'firstName', lastName: 'lastName', marks: 10}});
console.log(sizeOfStudentObject);

Apa yang Anda pikirkan?

Ala Eddine JEBALI
sumber
3
Ini melewatkan fungsi. Jika saya menambahkan fungsi, objek tidak muncul sebagai lebih besar
Don Rhummy
Tidak menghitung kunci
ebg11
7

saya ingin tahu apakah upaya pengurangan memori saya benar-benar membantu mengurangi memori

Menindaklanjuti komentar ini, inilah yang harus Anda lakukan: Cobalah untuk menghasilkan masalah memori - Tulis kode yang membuat semua objek ini dan secara besar meningkatkan batas atas hingga Anda mengalami masalah (Peramban peramban, Pembekuan peramban, atau Di luar- kesalahan memori). Idealnya Anda harus mengulang percobaan ini dengan browser yang berbeda dan sistem operasi yang berbeda.

Sekarang ada dua opsi: opsi 1 - Anda tidak berhasil menghasilkan masalah memori. Karenanya, Anda tidak perlu khawatir. Anda tidak memiliki masalah memori dan program Anda baik-baik saja.

opsi 2- Anda memang mendapatkan masalah memori. Sekarang tanyakan pada diri Anda apakah batas di mana masalah terjadi masuk akal (dengan kata lain: apakah mungkin jumlah objek ini akan dibuat pada penggunaan normal kode Anda). Jika jawabannya 'Tidak' maka Anda baik-baik saja. Kalau tidak, Anda sekarang tahu berapa banyak objek yang dapat dibuat oleh kode Anda. Mengolah algoritma sedemikian rupa sehingga tidak melanggar batas ini.

Itay Maman
sumber
Dari sudut pandang memori, ekstensi saya menambahkan sejumlah objek untuk setiap halaman / tab yang terbuka di Firefox. "Angka" sebanding dengan ukuran halaman. Dengan asumsi bahwa "kekuatan" pengguna memiliki antara 15 - 20 tab terbuka, dan jika halaman web memiliki banyak konten, browser menjadi lambat dan sangat tidak responsif setelah beberapa waktu. Ini terjadi bahkan tanpa saya secara eksplisit mencoba menekankan aplikasi. Saya punya rencana untuk menulis ulang kode yang saya pikir akan mengurangi banyak pembuatan objek. Saya hanya ingin memastikan bahwa tidak. objek berkurang berjumlah sesuatu sehingga layak
@Senthil: tetapi ukuran objek tidak memiliki arti kecuali Anda tahu jumlah memori yang tersedia. Karena jumlah memori kemungkinan akan tetap menjadi misteri, berbicara dalam hal #objects sama berguna dengan berbicara dalam hal #bytes
Itay Maman
5

Pustaka Javascript ini sizeof.jsmelakukan hal yang sama. Sertakan seperti ini

<script type="text/javascript" src="sizeof.js"></script>

Fungsi sizeof mengambil objek sebagai parameter dan mengembalikan ukuran perkiraannya dalam byte. Sebagai contoh:

// define an object
var object =
    {
      'boolean' : true,
      'number'  : 1,
      'string'  : 'a',
      'array'   : [1, 2, 3]
    };

// determine the size of the object
var size = sizeof(object);

Fungsi sizeof dapat menangani objek yang berisi banyak referensi ke objek lain dan referensi rekursif.

Awalnya diterbitkan di sini .

Jayram
sumber
Ini lebih lambat dan tampaknya "kurang tepat" daripada @liangliang, dalam kasus penggunaan saya.
cregox
2

Terima kasih banyak kepada semua orang yang telah mengerjakan kode untuk ini!

Saya hanya ingin menambahkan bahwa saya telah mencari hal yang persis sama, tetapi dalam kasus saya ini adalah untuk mengelola cache objek yang diproses untuk menghindari keharusan mem-parsing dan memproses objek dari panggilan ajax yang mungkin atau mungkin belum di-cache oleh browser. Ini sangat berguna untuk objek yang membutuhkan banyak pemrosesan, biasanya segala sesuatu yang tidak dalam format JSON, tetapi bisa sangat mahal untuk menyimpan hal-hal ini dalam cache dalam proyek besar atau aplikasi / ekstensi yang dibiarkan berjalan untuk waktu yang lama waktu.

Bagaimanapun, saya menggunakannya untuk sesuatu seperti:

var myCache = {
    cache: {},
    order: [],
    size: 0,
    maxSize: 2 * 1024 * 1024, // 2mb

    add: function(key, object) {
        // Otherwise add new object
        var size = this.getObjectSize(object);
        if (size > this.maxSize) return; // Can't store this object

        var total = this.size + size;

        // Check for existing entry, as replacing it will free up space
        if (typeof(this.cache[key]) !== 'undefined') {
            for (var i = 0; i < this.order.length; ++i) {
                var entry = this.order[i];
                if (entry.key === key) {
                    total -= entry.size;
                    this.order.splice(i, 1);
                    break;
                }
            }
        }

        while (total > this.maxSize) {
            var entry = this.order.shift();
            delete this.cache[entry.key];
            total -= entry.size;
        }

        this.cache[key] = object;
        this.order.push({ size: size, key: key });
        this.size = total;
    },

    get: function(key) {
        var value = this.cache[key];
        if (typeof(value) !== 'undefined') { // Return this key for longer
            for (var i = 0; i < this.order.length; ++i) {
                var entry = this.order[i];
                if (entry.key === key) {
                    this.order.splice(i, 1);
                    this.order.push(entry);
                    break;
                }
            }
        }
        return value;
    },

    getObjectSize: function(object) {
        // Code from above estimating functions
    },
};

Ini adalah contoh sederhana dan mungkin memiliki beberapa kesalahan, tetapi memberikan ide, karena Anda dapat menggunakannya untuk memegang objek statis (konten tidak akan berubah) dengan tingkat kecerdasan tertentu. Hal ini dapat secara signifikan mengurangi persyaratan pemrosesan yang mahal yang harus dilakukan oleh objek.

Haravikk
sumber
1
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;
}
Boris Rayskiy
sumber
1

Saya menggunakan tab Timeline alat dev Chrome , instantiate objek dalam jumlah yang semakin besar, dan mendapatkan perkiraan yang baik seperti itu. Anda dapat menggunakan html seperti ini di bawah ini, sebagai boilerplate, dan memodifikasinya untuk lebih mensimulasikan karakteristik objek Anda (jumlah dan jenis properti, dll ...). Anda mungkin ingin mengeklik ikon bit sampah di bagian bawah tab alat dev, sebelum dan sesudah menjalankan.

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

Instantiasi 2 juta objek masing-masing hanya satu properti (seperti dalam kode ini di atas) mengarah ke perhitungan kasar 50 byte per objek, pada Chromium saya, sekarang. Mengubah kode untuk membuat string acak per objek menambahkan sekitar 30 byte per objek, dll. Semoga ini bisa membantu.

matanster
sumber
-3

Saya yakin Anda lupa memasukkan 'array'.

  typeOf : function(value) {
        var s = typeof value;
        if (s === 'object')
        {
            if (value)
            {
                if (typeof value.length === 'number' && !(value.propertyIsEnumerable('length')) && typeof value.splice === 'function')
                {
                    s = 'array';
                }
            }
            else
            {
                s = 'null';
            }
        }
        return s;
    },

   estimateSizeOfObject: function(value, level)
    {
        if(undefined === level)
            level = 0;

        var bytes = 0;

        if ('boolean' === typeOf(value))
            bytes = 4;
        else if ('string' === typeOf(value))
            bytes = value.length * 2;
        else if ('number' === typeOf(value))
            bytes = 8;
        else if ('object' === typeOf(value) || 'array' === typeOf(value))
        {
            for(var i in value)
            {
                bytes += i.length * 2;
                bytes+= 8; // an assumed existence overhead
                bytes+= estimateSizeOfObject(value[i], 1)
            }
        }
        return bytes;
    },

   formatByteSize : function(bytes)
    {
        if (bytes < 1024)
            return bytes + " bytes";
        else
        {
            var floatNum = bytes/1024;
            return floatNum.toFixed(2) + " kb";
        }
    },
fchas15
sumber
1
Dalam JS, array adalah objek. Mungkin ada beberapa optimasi dalam implementasi, tetapi secara konseptual array dan objek adalah sama.
Kris Walker
-8

Saya tahu ini sama sekali bukan cara yang tepat untuk melakukannya, namun ini telah membantu saya beberapa kali di masa lalu untuk mendapatkan ukuran file objek kira-kira:

Tulis objek / respons Anda ke konsol atau tab baru, salin hasilnya ke file notepad baru, simpan, dan periksa ukuran file. File notepad itu sendiri hanya beberapa byte, sehingga Anda akan mendapatkan ukuran file objek yang cukup akurat.

Jeffrey Roosendaal
sumber
4
Ini sepenuhnya salah. Sebagai contoh, pertimbangkan angka 1/3 = 0.3333333333333333. Ini akan menjadi 18 byte menggunakan pendekatan Anda.
korCZis
2
Saya mengatakan itu perkiraan . Terkadang Anda tidak peduli apakah itu 1MB atau 1,00001MB, Anda hanya ingin tahu perkiraan, maka metode ini baik-baik saja.
Jeffrey Roosendaal
Solusi
pipi