Saya memiliki model dengan mungkin ribuan benda-benda. Aku bertanya-tanya apa yang akan menjadi cara yang paling efisien untuk menyimpan mereka dan mengambil satu objek setelah saya memiliki itu's id. Id's adalah nomor yang panjang.
Jadi ini adalah 2 pilihan yang saya pikirkan. dalam opsi satu itu's sederhana array dengan menaikkan indeks. dalam opsi 2's array asosiatif dan mungkin suatu obyek, apakah itu membuat perbedaan. Pertanyaan saya adalah mana yang lebih efisien, ketika aku lebih sering perlu untuk mengambil sebuah objek tunggal, tetapi juga kadang-kadang loop melalui mereka dan memilah.
Opsi satu dengan non-asosiatif array:
var a = [{id: 29938, name: 'name1'},
{id: 32994, name: 'name1'}];
function getObject(id) {
for (var i=0; i < a.length; i++) {
if (a[i].id == id)
return a[i];
}
}
Opsi dua dengan array asosiatif:
var a = []; // maybe {} makes a difference?
a[29938] = {id: 29938, name: 'name1'};
a[32994] = {id: 32994, name: 'name1'};
function getObject(id) {
return a[id];
}
Update:
OK, saya mendapatkan bahwa menggunakan array di pilihan kedua adalah keluar dari pertanyaan. Jadi deklarasi line opsi kedua harus benar-benar: var a = {};
dan satu-satunya pertanyaan adalah: apa yang berkinerja lebih baik dalam mengambil sebuah objek dengan id yang diberikan: array atau objek dimana id adalah kunci.
dan juga, akan menjawab perubahan jika aku akan memiliki untuk mengurutkan daftar berkali-kali?
Versi pendek: Array sebagian besar lebih cepat dari benda-benda. Tapi tidak 100% benar solusi.
var a1 = [{id: 29938, name: 'name1'}, {id: 32994, name: 'name1'}];
var a2 = [];
a2[29938] = {id: 29938, name: 'name1'};
a2[32994] = {id: 32994, name: 'name1'};
var o = {};
o['29938'] = {id: 29938, name: 'name1'};
o['32994'] = {id: 32994, name: 'name1'};
for (var f = 0; f < 2000; f++) {
var newNo = Math.floor(Math.random()*60000+10000);
if (!o[newNo.toString()]) o[newNo.toString()] = {id: newNo, name: 'test'};
if (!a2[newNo]) a2[newNo] = {id: newNo, name: 'test' };
a1.push({id: newNo, name: 'test'});
}
Ada beberapa kesalahpahaman dalam pertanyaan anda.
Ini adalah array:
var a1 = [1, 2, 3];
var a2 = ["a", "b", "c"];
var a3 = [];
a3[0] = "a";
a3[1] = "b";
a3[2] = "c";
Ini adalah sebuah array, terlalu:
var a3 = [];
a3[29938] = "a";
a3[32994] = "b";
It's pada dasarnya merupakan array dengan lubang di dalamnya, karena setiap array memiliki continous pengindeksan. It's lebih lambat dari array tanpa lubang. Tapi iterasi secara manual melalui array bahkan lebih lambat (kebanyakan).
Ini adalah sebuah objek:
var a3 = {};
a3[29938] = "a";
a3[32994] = "b";
Berikut ini adalah tes kinerja dari tiga kemungkinan:
Baca tentang topik ini di Smashing Magazine: Tulisan memori cepat efisien JavaScript
It's tidak benar-benar kinerja yang bersangkutan pada semua, karena array dan objek pekerjaan yang sangat berbeda (atau seharusnya, setidaknya). Array memiliki terus-menerus index 0..n
, sedangkan objek peta sembarang tombol untuk sembarang nilai. Jika anda ** ingin menyediakan kunci tertentu, satu-satunya pilihan adalah suatu objek. Jika anda don't peduli tentang kunci-kunci, array itu.
Jika anda mencoba untuk mengatur sewenang-wenang (numerik) tombol pada sebuah array, anda benar-benar memiliki kinerja kehilangan, karena perlakuan array akan mengisi semua indeks di antaranya:
> foo = [];
[]
> foo[100] = 'a';
"a"
> foo
[undefined, undefined, undefined, ..., "a"]
(Perhatikan bahwa array yang tidak benar-benar * mengandung 99 undefined
nilai-nilai, tetapi ia akan berperilaku dengan cara ini karena anda're [seharusnya] iterasi* array di beberapa titik.)
The literal untuk kedua pilihan harus membuatnya sangat jelas bagaimana mereka dapat digunakan:
var arr = ['foo', 'bar', 'baz']; // no keys, not even the option for it
var obj = { foo : 'bar', baz : 42 }; // associative by its very nature
Dengan ES6 paling performant cara untuk menggunakan Peta.
var myMap = new Map();
myMap.set(1, 'myVal');
myMap.set(2, { catName: 'Meow', age: 3 });
myMap.get(1);
myMap.get(2);
Anda dapat menggunakan fitur-fitur ES6 hari ini menggunakan shim (https://github.com/es-shims/es6-shim).
Kinerja akan bervariasi tergantung pada browser dan skenario. Tapi di sini adalah salah satu contoh di mana Peta
yang paling performant: https://jsperf.com/es6-map-vs-object-properties/2
REFERENSI https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map
Di Indonesia jika anda tahu ID
, perulangan melalui array sangat lambat dibandingkan dengan objek[ID]
.
const uniqueString = require('unique-string');
const obj = {};
const arr = [];
var seeking;
//create data
for(var i=0;i<1000000;i++){
var getUnique = `${uniqueString()}`;
if(i===888555) seeking = getUnique;
arr.push(getUnique);
obj[getUnique] = true;
}
//retrieve item from array
console.time('arrTimer');
for(var x=0;x<arr.length;x++){
if(arr[x]===seeking){
console.log('Array result:');
console.timeEnd('arrTimer');
break;
}
}
//retrieve item from object
console.time('objTimer');
var hasKey = !!obj[seeking];
console.log('Object result:');
console.timeEnd('objTimer');
Dan hasilnya:
Array result:
arrTimer: 12.857ms
Object result:
objTimer: 0.051ms
Bahkan jika mencari ID adalah salah satu yang pertama di hotel/objek:
Array result:
arrTimer: 2.975ms
Object result:
objTimer: 0.068ms
Saya mencoba untuk mengambil ini ke dimensi berikutnya, secara harfiah.
Diberikan sebuah array 2 dimensi, di mana sumbu x dan y selalu sama panjang, itu lebih cepat untuk:
a) mencari sel dengan menciptakan dua dimensi array dan mencari indeks pertama, diikuti oleh indeks kedua, saya.e:
var arr=[][]
var cell=[x][y]
atau
b) membuat sebuah objek dengan representasi string dari koordinat x dan y, dan kemudian melakukan pencarian pada obj, saya.e:
var obj={}
var cell = obj['x,y']
Hasilnya: Ternyata bahwa itu's jauh lebih cepat untuk melakukan dua angka indeks pencarian pada array, dari satu properti lookup pada objek.
Hasil berikut ini:
Hal ini tergantung pada penggunaan. Jika kasus ini lookup benda-benda yang sangat cepat.
Berikut ini adalah Plunker contoh untuk menguji kinerja dari array dan objek pencarian.
https://plnkr.co/edit/n2expPWVmsdR3zmXvX4C?p=preview
Anda akan melihat bahwa;
Mencari untuk 5.000 barang-barang di 5.000 panjang array collection, mengambil alih 3000
milisecons
Namun mendongak untuk 5.000 barang-barang di objek memiliki 5.000 sifat, mengambil hanya 2
atau 3
milisecons
Juga membuat objek pohon don't membuat perbedaan besar
Saya punya masalah yang sama yang saya hadapi di mana saya perlu untuk menyimpan live lilin dari sebuah event sumber yang terbatas untuk x item. Saya bisa memiliki mereka disimpan dalam sebuah objek di mana timestamp dari setiap candle akan bertindak sebagai kunci dan lilin itu sendiri akan bertindak sebagai nilai. Kemungkinan lain adalah bahwa saya bisa menyimpannya dalam array dimana setiap item adalah lilin itu sendiri. Satu masalah tentang hidup lilin adalah bahwa mereka tetap mengirimkan update pada timestamp yang sama di mana update terbaru memegang data terbaru oleh karena itu anda juga update item yang ada atau menambahkan yang baru. Jadi di sini adalah acuan yang berusaha untuk menggabungkan semua 3 kemungkinan. Array dalam larutan di bawah ini yang minimal 4x lebih cepat rata-rata. Merasa bebas untuk bermain
"use strict";
const EventEmitter = require("events");
let candleEmitter = new EventEmitter();
//Change this to set how fast the setInterval should run
const frequency = 1;
setInterval(() => {
// Take the current timestamp and round it down to the nearest second
let time = Math.floor(Date.now() / 1000) * 1000;
let open = Math.random();
let high = Math.random();
let low = Math.random();
let close = Math.random();
let baseVolume = Math.random();
let quoteVolume = Math.random();
//Clear the console everytime before printing fresh values
console.clear()
candleEmitter.emit("candle", {
symbol: "ABC:DEF",
time: time,
open: open,
high: high,
low: low,
close: close,
baseVolume: baseVolume,
quoteVolume: quoteVolume
});
}, frequency)
// Test 1 would involve storing the candle in an object
candleEmitter.on('candle', storeAsObject)
// Test 2 would involve storing the candle in an array
candleEmitter.on('candle', storeAsArray)
//Container for the object version of candles
let objectOhlc = {}
//Container for the array version of candles
let arrayOhlc = {}
//Store a max 30 candles and delete older ones
let limit = 30
function storeAsObject(candle) {
//measure the start time in nanoseconds
const hrtime1 = process.hrtime()
const start = hrtime1[0] * 1e9 + hrtime1[1]
const { symbol, time } = candle;
// Create the object structure to store the current symbol
if (typeof objectOhlc[symbol] === 'undefined') objectOhlc[symbol] = {}
// The timestamp of the latest candle is used as key with the pair to store this symbol
objectOhlc[symbol][time] = candle;
// Remove entries if we exceed the limit
const keys = Object.keys(objectOhlc[symbol]);
if (keys.length > limit) {
for (let i = 0; i < (keys.length - limit); i++) {
delete objectOhlc[symbol][keys[i]];
}
}
//measure the end time in nano seocnds
const hrtime2 = process.hrtime()
const end = hrtime2[0] * 1e9 + hrtime2[1]
console.log("Storing as objects", end - start, Object.keys(objectOhlc[symbol]).length)
}
function storeAsArray(candle) {
//measure the start time in nanoseconds
const hrtime1 = process.hrtime()
const start = hrtime1[0] * 1e9 + hrtime1[1]
const { symbol, time } = candle;
if (typeof arrayOhlc[symbol] === 'undefined') arrayOhlc[symbol] = []
//Get the bunch of candles currently stored
const candles = arrayOhlc[symbol];
//Get the last candle if available
const lastCandle = candles[candles.length - 1] || {};
// Add a new entry for the newly arrived candle if it has a different timestamp from the latest one we storeds
if (time !== lastCandle.time) {
candles.push(candle);
}
//If our newly arrived candle has the same timestamp as the last stored candle, update the last stored candle
else {
candles[candles.length - 1] = candle
}
if (candles.length > limit) {
candles.splice(0, candles.length - limit);
}
//measure the end time in nano seocnds
const hrtime2 = process.hrtime()
const end = hrtime2[0] * 1e9 + hrtime2[1]
console.log("Storing as array", end - start, arrayOhlc[symbol].length)
}
Kesimpulan 10 adalah batas di sini
Storing as objects 4183 nanoseconds 10
Storing as array 373 nanoseconds 10
Jika anda memiliki sebuah array diurutkan maka anda dapat melakukan pencarian biner dan yang jauh lebih cepat dari sebuah objek lookup, anda bisa lihat jawaban saya di sini: https://stackoverflow.com/questions/57422718/how-to-search-faster-in-a-sorted-array-using-javascript