2013-09-27 152 views
12

Vì vậy, đây là một điều thú vị ... Trong khi tôi thử nghiệm hiệu suất của thuộc tính setAttribute so với thuộc tính bình thường trên một phần tử, tôi đã tìm thấy một hành vi kỳ quặc sau đó thử nghiệm trên các đối tượng thường xuyên và ... Nó vẫn còn kỳ quặc!Hiệu suất của Chrome: tên thuộc tính "chuẩn" so với tiêu chuẩn

Vì vậy, nếu bạn có một đối tượng A = {}, và bạn đặt thuộc tính của nó như A['abc_def'] = 1 hoặc A.abc_def = 1, về cơ bản chúng giống nhau. Nhưng sau đó nếu bạn thực hiện A['abc-def'] = 1 hoặc A['123-def'] = 1 thì bạn gặp sự cố. Nó đi chậm hơn. Tôi thiết lập một thử nghiệm tại đây: http://jsfiddle.net/naPYL/1/. Tất cả đều hoạt động giống nhau trên tất cả các trình duyệt ngoại trừ chrome. Điều thú vị là đối với thuộc tính "abc_def", chrome thực sự nhanh hơn Firefox và IE, như tôi mong đợi. Nhưng đối với "abc-def" thì ít nhất gấp đôi. Vì vậy, những gì xảy ra ở đây về cơ bản (ít nhất là từ các thử nghiệm của tôi) là khi sử dụng cú pháp "đúng" cho các thuộc tính (cú pháp C hợp pháp, mà bạn có thể sử dụng với các thuộc tính dấu chấm) - Thật nhanh, nhưng khi bạn sử dụng cú pháp yêu cầu sử dụng dấu ngoặc vuông (a [...]) thì bạn gặp sự cố.

Tôi đã cố gắng tưởng tượng chi tiết triển khai nào sẽ phân biệt theo cách giữa hai chế độ và không thể. Bởi vì khi tôi nghĩ về nó, nếu bạn hỗ trợ những cái tên phi tiêu chuẩn đó, bạn có thể dịch tất cả các tên sang cùng một cơ chế, và phần còn lại chỉ là cú pháp được biên dịch vào cơ chế đó. Vì thế . cú pháp và [] phải giống nhau sau khi biên dịch. Nhưng rõ ràng có điều gì đó đang diễn ra theo cách khác ở đây ...

Nếu không nhìn vào mã nguồn của V8, bất kỳ ai cũng có thể nghĩ ra câu trả lời thực sự thỏa mãn không? (Hãy nghĩ về nó như một tập thể dục :-))

Here's also a quick jsperf.com example

Nhờ NDM cho ví dụ jsperf!

Edit:

Để làm rõ, tất nhiên tôi cũng muốn có một câu trả lời cụ thể từ các mã thực (mà tôi đã tìm thấy) hoặc chính xác hơn - lý do đằng sau đó thực hiện cụ thể. Đó là một trong những lý do tôi yêu cầu bạn xem xét nó "như một bài tập", để xem xét kỹ thuật thực hiện kỹ thuật và cố gắng tìm ra lý do.

Nhưng tôi cũng muốn xem cách thức hoạt động của những người khác trong những trường hợp như thế này. Điều này nghe có vẻ "mơ hồ" đối với một số người trong số các bạn - nhưng rất hữu ích khi cố gắng và suy nghĩ như những người khác theo thời gian hoặc xem quan điểm của họ. Nó tăng cường cách suy nghĩ của riêng bạn.

+4

Câu hỏi hay. V8 có cơ chế lớp sao lưu sẽ cố gắng ghép nối một lớp C++ chuẩn thành các đối tượng để tăng tốc độ. Nó có thể là -it có vẻ như, trên thực tế, khi cú pháp là không chuẩn, lớp sao lưu này không thể được xây dựng, do đó Chrome xử lý thuộc tính theo cách tiêu chuẩn (bảng băm nhất có thể). – GameAlchemist

+1

Tôi đã thêm một bài kiểm tra jsperf và liên kết nó trong câu hỏi của bạn. FYI trên chrome của tôi nó đã được 6% chậm hơn. Trong FF, chúng nhanh như nhau, nhưng nhanh gấp 7 lần so với chrome! – NDM

+1

Tôi nghĩ rằng câu hỏi này có nguy cơ bị đóng cửa chủ yếu là do * "mà không nhìn vào mã nguồn của V8 [...] nghĩ về nó như là một bài tập" * dòng. Đây là một câu hỏi thú vị, nhưng dòng đó khuyến khích đầu cơ thay vì các câu trả lời cụ thể, và điều đó thường bị cau mày. –

Trả lời

5

Vì vậy, các đối tượng JS có thể được sử dụng cho hai mục đích xung đột. Chúng có thể được sử dụng như các đối tượng nhưng chúng cũng có thể được sử dụng như các bảng băm. Tuy nhiên những gì là nhanh chóng và có ý nghĩa cho các đối tượng không phải là như vậy cho bảng băm, do đó, V8 cố gắng đoán những gì một đối tượng nhất định.

Một số dấu hiệu người dùng có thể cho rằng anh muốn từ điển đang xóa thuộc tính hoặc giving a property a name that cannot be accessed using dot notation.

Một số chẩn đoán khác cũng được sử dụng, tôi đã thực hiện một ý chính https://gist.github.com/petkaantonov/6327915.

Có tuy nhiên là a really cool hack rằng redempts một đối tượng từ băm bảng địa ngục:

function ensureFastProperties(obj) { 
    function f() {} 
    f.prototype = obj; 
    return obj; 
} 

Nhìn thấy nó trong hành động: http://jsperf.com/property-dash-parformance/2.

Đối tượng được rút lại không nhanh như đối tượng gốc bởi vì các thuộc tính được lưu trữ trong mảng thuộc tính bên ngoài thay vì trong đối tượng. Nhưng điều đó vẫn còn tốt hơn nhiều so với bảng băm. Lưu ý rằng đây vẫn là điểm chuẩn khá bị hỏng, không suy nghĩ trong giây lát rằng các bảng băm chỉ chậm hơn 2x so với các thuộc tính inobject.

+0

Các hack mát mẻ dường như không hoạt động trong 'Chrome 30.0.1599.65 beta-m' – C5H8NNaO4

+0

@ C5H8NNaO4 yea cần phải điều tra .. mã để tối ưu hóa đối tượng trong phân công nguyên mẫu vẫn còn ở đó ngay cả trên hầu hết các cạnh chảy máu v8 – Esailija