2011-10-31 4 views
19

Câu hỏi này gần giống với How to efficiently count the number of keys/properties of an object in JavaScript?.Tính hiệu quả số lượng khóa/thuộc tính của một đối tượng trong JavaScript

Tôi muốn biết thêm một phần thông tin: "hằng số thời gian" cách xác định số lượng khóa trong đối tượng? Tôi chủ yếu quan tâm đến việc thực hiện điều này trong Node.JS, vì hầu hết các đối tượng trên trình duyệt không quá lớn để có mối quan tâm lớn.

EDIT: Dường như Object.keys(obj).length lợi nhuận trong thời gian tuyến tính O (n) trong Google Chrome và trong Node.js (ví dụ: phụ thuộc vào số lượng các phím trong obj). Có phương pháp O (1) nào tốt hơn không?

tôi đã làm một số thử nghiệm trong Node.js (nguồn là bên dưới)

var tests = [10e3, 10e4, 10e5, 10e6] 
for(j in tests) { 
    var obj = {}; 
    for(i = 0; i < tests[j]; i++) 
     obj[i] = i; 
    console.time('test' + tests[j]); 
    Object.keys(obj).length; 
    console.timeEnd('test' + tests[j]); 
} 

Đối với n = 10e3, 10e4, 10e5, 10e6 ... kết quả là:

test10000: 5ms 
test100000: 20ms 
test1000000: 371ms 
test10000000: 4009ms 
+0

Bạn đã thử kiểm tra điều này chưa? – Blender

+0

Không. Hôm nay tôi cảm thấy lười biếng ...:/Trường hợp thứ Hai, tôi cho là vậy. – BMiner

+2

Tôi nghi ngờ rằng nhận được ".length" từ kết quả của việc gọi "Object.keys()" là không đổi-thời gian, nhưng tôi cũng nghi ngờ rằng gọi "Object.keys()" là tuyến tính trong số lượng tài sản. – Pointy

Trả lời

1

Xem nguồn , cụ thể GetLocalElementKeys

v8 objects.cc

+0

Tôi quá lười biếng để làm điều này. Vui lòng nói tiếng Anh. Tôi sẵn sàng chấp nhận câu trả lời của bạn. : P – BMiner

+0

Tùy thuộc vào những gì đối tượng chứa chúng làm những việc khác nhau, trường hợp xấu nhất dường như đang làm 1 cho vòng lặp thông qua tất cả các yếu tố. – Andrew

5

Sau một chút nghiên cứu, không có cách nào để xác định số lượng các khóa trong một đối tượng JavaScript trong thời gian liên tục, ít nhất là không có trong Node ... và chưa hoàn toàn. Nút nội bộ theo dõi thông tin này, nhưng nó không lộ ra, vì không có phương pháp để làm như vậy trong ECMA-262 thứ năm.

Cần lưu ý rằng Harmony (ECMA phiên bản 6) có thể hỗ trợ Bản đồ và Bộ. Bạn không chắc chắn những gì spec cho những sẽ bật ra được.

Tôi được thông báo rằng chúng tôi cần đưa điều này lên với ủy ban TC39.

báo cáo lỗi cho V8: http://code.google.com/p/v8/issues/detail?id=1800

1

ECMA 6 hòa giới thiệu MapSet lớp mà có thể bạn có thể sử dụng (trong tương lai :)

var map = new Map; 
map.set('a', 'b'); 
console.log(map.size); // prints 1 

Tôi tin rằng nó nên có độ phức tạp O (1), không thử mặc dù. Bạn có thể chạy nó trong nút 0.11+ qua node --harmony script.js.


Một cách khác là sử dụng Proxy lớp mà cũng đã được thêm vào trong hòa.