2013-02-01 31 views
5

Tôi đã chơi với một số tối ưu hóa hiệu suất javascript và tìm thấy một cái gì đó thú vị. Đây là mã:Hiệu suất: sử dụng mảng trong không gian tên đối tượng so với mảng cục bộ

function gObject() { 

    this.obj = []; 
    this.LIMIT = 100000; 

    this.doLoopLocal = function() { 
     var o = []; 
     for (var i=0;i<this.LIMIT;i+=1) { 
      o.push(i); 
     } 
     return o; 
    };  

    this.doLoopObject = function() { 
     this.obj = []; 
     for (var i=0;i<this.LIMIT;i+=1) { 
      this.obj.push(i); 
     } 
    }; 
}; 

var g = new gObject(); 

console.time('Using Local array'); 
g.doLoopLocal(); 
console.timeEnd('Using Local array'); 

console.time('Using Object array'); 
g.doLoopObject(); 
console.timeEnd('Using Object array'); 

Khi tôi chạy nó, nhật ký nói với tôi rằng việc sử dụng các mảng địa phương là chậm hơn so với sử dụng mảng được định nghĩa trong namespace đối tượng. Sự khác biệt là đáng kể - 8 đến 10 lần! (FF 18.0.1)

Using Local array: 16ms 
Using Object array: 2ms 

Một ảnh chụp màn hình: enter image description here

Tôi đã luôn luôn giả định rằng việc sử dụng đối tượng quy định tại địa phương trong phạm vi chức năng là nhanh hơn, nhưng thí nghiệm này cho thấy tôi sai. Tại sao điều này sẽ xảy ra?

CẬP NHẬT: Tôi đã thử tập lệnh trong bảng điều khiển Firefox cục bộ và các con số là thứ tôi mong đợi ở địa điểm đầu tiên: sử dụng mảng địa phương hoạt động tốt hơn bằng mảng đối tượng. Vì vậy, nguyên nhân thực sự là Firebug cho một số lý do nghiêng các con số và hiển thị kết quả không chính xác. Một cái gì đó để giữ trong tâm trí.

+0

Tôi đã dán mã này vào bảng điều khiển của mình trong chrome và mảng cục bộ mất 2 mili giây và mảng Đối tượng mất 3 mili giây .. thú vị. Điều gì sẽ xảy ra nếu bạn hoán đổi thứ tự, chạy thứ hai địa phương? –

+0

Tôi cũng đã chạy điều này trong Chrome và nhận: "Sử dụng mảng cục bộ: 1.675ms Sử dụng mảng Đối tượng: 3.585ms" lần đầu tiên. Sau khi lặp lại mã rất giống nhau ba lần tôi nhận được "Sử dụng mảng cục bộ: 2.316ms Sử dụng mảng Đối tượng: 1.673ms". Thậm chí thú vị hơn ... –

+0

mảng cục bộ mất 1ms và mảng đối tượng mất 6ms trong Chrome cho tôi. –

Trả lời

1

Như mọi khi với phép thuật, ma thuật nằm trong đôi mắt tin rằng nó đang xảy ra.
Bạn đang thử nghiệm điều gì ở đây bằng cách này? Nếu chúng ta quên rằng, trong doLoopObject của bạn, bạn không trả về this.obj, chỉ cần kiểm tra một vài lần cho thấy kết quả là 'ngẫu nhiên', thậm chí tệ hơn: nếu bạn đảo ngược thứ tự các bài kiểm tra, chúng có thể thay đổi tùy thuộc vào Trình duyệt. Và kết quả sẽ phụ thuộc vào thời gian bạn đợi giữa hai lần nhấp. Nếu bạn chờ một vài giây, chúng sẽ luôn gần như bằng nhau.
Bây giờ hãy chú ý, trên JSPerf, với tốc độ các con số đang tăng lên, và đặc biệt là trên Firefox, lời giải thích trở nên khá rõ ràng: có sự chậm lại định kỳ: bộ thu gom rác được kích hoạt bởi các chức năng tạo rác. Khi nó kích hoạt, các số liệu sẽ tăng chậm hơn, có thể là đối tượng hoặc một biến cục bộ (không quan trọng). Những gì bạn đang đo ở đây là thời gian thu gom rác, KHÔNG phải là thời gian đẩy() trên một thuộc tính đối tượng so với biến cục bộ. Điều đó giải thích tại sao thứ tự, và thời gian giữa các bài kiểm tra, thay đổi mọi thứ.
Tôi sẽ thêm rằng sự thay đổi giữa hai bài kiểm tra là quá lớn để kết luận bất cứ điều gì.

Nhưng quan trọng nhất là, khi chờ đợi đủ, cả hai bài kiểm tra thực hiện tương tự trên FF/Safari ...

Kết luận duy nhất mà bạn có thể rút ra từ tất cả điều này là: cả hai phương pháp thực hiện tương tự.

NHƯNG Vì bất kỳ ai phân bổ nhiều 'đống' sẽ phân bổ cùng một lúc, sử dụng myArray đơn giản [lastIndex-1] = 0, tôi sợ kết luận thực sự là: kiểm tra này không hiển thị gì cả.

Các vấn đề liên quan