2011-11-08 39 views
32

Trong JavaScript, có sự khác biệt về hiệu suất giữa việc sử dụng số double bằng (==) hay không bằng cách sử dụng số ba bằng (===)?Sự khác biệt về hiệu suất của JavaScript giữa hai bằng (==) và ba bằng (===)

Ví dụ: if (foo == bar) vs if (foo === bar)

+20

Không có gì bạn từng thấy. Di chuyển trên. –

+2

Chúng phục vụ các mục đích khác nhau và "hiệu suất cao hơn" không phải là một trong số chúng. Đó không phải là vấn đề, hãy sử dụng chúng khi bạn muốn có được chức năng mà chúng cung cấp. – meagar

+0

Đề nghị đọc: [Bạn không biết JS] (https://github.com/getify/You-Dont-Know-JS/blob/master/types%20&%20grammar/ch4.md#loose-equals-vs -strict-equals) –

Trả lời

25

so sánh nghiêm ngặt (===) sẽ luôn luôn được nhanh hơn một chút, nhưng the difference is usually negligible.

Nó chắc chắn có ý nghĩa để thích === nếu bạn biết chắc chắn rằng bạn không cần ép buộc loại trong so sánh. Nó sẽ luôn có tốc độ nhanh nhất là ==.

+3

Vui, vì '==' đánh bại '===' đối với tôi, trong cả hai lần tôi chạy thử nghiệm, trên FF7. Tôi đồng ý rằng '===' nên được nhanh hơn, nhưng các thử nghiệm tuyên bố khác. (có thể là sự khác biệt trong tải Javascript/CPU, ai biết) – Nightfirecat

+0

@Nightfirecat: Điều đó thật thú vị. Bạn có so sánh các biến hoặc chữ? –

+0

Tôi chỉ sử dụng các thử nghiệm mặc định mà nó đã sử dụng - cụ thể là "==/=== trên cùng một loại" kiểm tra, vì chúng là nhanh nhất trong số chúng. Tôi tin rằng cùng một mô hình xuất hiện trong tất cả các so sánh theo loại so với các bài kiểm tra so sánh thông thường, không nhớ. – Nightfirecat

3

Do hiệu suất, tôi nghĩ === có hiệu suất tốt hơn, bởi vì === là nghiêm ngặt hơn ==,

ví dụ hãy thử những điều sau trong bảng điều khiển Chrome.

> 1 == '1' 
    true 
> 1 === '1' 
    false 

== có để kiểm tra điều hơn ===

1

Từ một số thử nghiệm mỏng manh, == có vẻ nhanh hơn ===.

Bằng cách này, tôi có nghĩa là tôi có thể thấy một vài phần nghìn giây khác nhau về sự tương tác của hàng triệu thử nghiệm. Bạn không thể có thể cần đạt được hiệu suất, thay vì sử dụng bất cứ điều gì là chính xác nhất cho nhiệm vụ trong tầm tay.

EDIT: thực sự, dường như phụ thuộc vào/bạn đang so sánh gì và triển khai trình duyệt. Nói cách khác, đừng lo lắng về nó.

+1

'===' nhanh hơn trong hầu hết các trường hợp. Có trường hợp cạnh (bạn tìm thấy một). Tuy nhiên, từ hướng dẫn thực hành mã/phong cách '===' thắng tay mỗi lần – Raynos

+2

"đừng lo lắng về nó", "Bạn không thể có thể cần đạt được hiệu suất". Bạn không biết ý định của người dùng này và tất cả người dùng đến đây cho câu hỏi này. – cdosborn

+2

@cdosborn woah, hello 2011. Điều này Q trước ngày thẻ nodejs trên SO. Vâng, bạn đúng. Vào thời điểm đó là một giả định công bằng rằng đây là trong trình duyệt, và cạo mili giây/triệu đánh giá sẽ là .. một sử dụng xấu thời gian của bạn. Mọi thứ đã thay đổi LOT trong ~ 5 năm. – Hamish

38
  • Nếu các loại so đều giống nhau, họ là giống hệt nhau. Tức là họ sử dụng cùng một thuật toán chính xác.

  • Nếu các loại là khác nhau, thì hiệu suất không liên quan. Hoặc là bạn cần ép buộc loại, hoặc bạn không. Nếu bạn không cần, đừng sử dụng == vì kết quả bạn nhận được có thể không mong muốn.

14

Edit: để tham khảo đây là bởi lời giải thích đặc tả bởi tiến sĩ Axel Rauschmayer http://www.2ality.com/2011/06/javascript-equality.html Really great ghi lên.

=== (Bình đẳng nghiêm ngặt): Chỉ xem xét các giá trị bằng nhau có cùng loại.

  1. không xác định === không xác định, null === null,
  2. NaN === gì kể cả chính nó,
  3. nguyên thủy [Số | Chuỗi | Boolean] === giá trị nguyên thủy bằng,
  4. tự (0 === -0)
  5. Hai đối tượng [mảng | Object | Function] === Chỉ tự (giống thực thể chính xác)

== (khoan dung bình đẳng)

  1. Nếu cả hai giá trị đều có cùng loại: so sánh với ===.
  2. không xác định == null
  3. số và chuỗi: string => số và so sánh
  4. boolean và phi boolean => phi boolean để số và so sánh
  5. chuỗi hoặc số => một đối tượng: chuyển đổi đối tượng để nguyên thủy và so sánh.

Trong tất cả môi trường Javascript hiện đại, chúng được triển khai hoàn toàn khác nhau. Nói một cách đơn giản, == kiểm tra tính tương đồng thông qua việc chuyển đổi các biến đã cho thành nguyên thủy (chuỗi, số, boolean). === kiểm tra đối với mẫu nghiêm ngặt, có nghĩa là chính xác cùng một đối tượng hoặc giá trị nguyên thủy mà không cần chuyển đổi.

Nếu bạn làm objOne == objTwo những gì thực sự xảy ra là [[EQUALS]].call(objOne.valueOf(), objTwo.valueOf())

Độ phân giải của valueOf có thể hơi tham gia, hoạt động kết nối chức năng tiếp xúc trong JS và các công cụ cơ nội bộ. Đủ để nói rằng so sánh sẽ luôn luôn kết thúc với hai giá trị ép buộc để nguyên thủy hoặc một lỗi sẽ được ném.

Chỉnh sửa:EQUALS trước hết thực hiện thử trước STRICT_EQUALS trước tiên hãy thử phần còn lại của quá trình.

Bit thú vị ở đây là valueOf (và đối tác toString) có thể ghi đè. Chạy đoạn mã này trong Chrome (Tôi nghĩ rằng bất kỳ webkit nào, không chắc chắn liệu JSC và V8 có chia sẻ miếng ngon này) hay không. Nó sẽ thổi mindpiece của bạn:

var actions = []; 
var overload = { 
    valueOf: function(){ 
    var caller = arguments.callee.caller; 
    actions.push({ 
     operation: caller.name, 
     left: caller.arguments[0] === this ? "unknown" : this, 
     right: caller.arguments[0] 
    }); 
    return Object.prototype.toString.call(this); 
    } 
}; 
overload.toString = overload.valueOf; 
overload == 10; 
overload === 10; 
overload * 10; 
10/overload; 
overload in window; 
-overload; 
+overload; 
overload < 5; 
overload > 5; 
[][overload]; 
overload == overload; 
console.log(actions); 

Output:

[ { operation: 'EQUALS', 
    left: overload, 
    right: 10 }, 
    { operation: 'MUL', 
    left: overload, 
    right: 10 }, 
    { operation: 'DIV', 
    left: 'unknown', 
    right: overload }, 
    { operation: 'IN', 
    left: overload, 
    right: DOMWindow }, 
    { operation: 'UNARY_MINUS', 
    left: overload, 
    right: undefined }, 
    { operation: 'TO_NUMBER', 
    left: overload, 
    right: undefined }, 
    { operation: 'COMPARE', 
    left: overload, 
    right: 5 }, 
    { operation: 'COMPARE', 
    left: 'unknown', 
    right: overload }, 
    { operation: 'ToString', 
    left: 'unknown', 
    right: overload } ] 

Bản chất của sự khác biệt giữa ===== được minh họa bằng === không hiển thị trong danh sách đó. Nó bỏ qua cuộc hành trình vào JavascriptLand hoàn toàn. Cuộc phiêu lưu đó là tốn kém khi so sánh hiệu suất.

Tuy nhiên, bạn cần tính đến tối ưu hóa công cụ. Đối với hầu hết các đối tượng, động cơ sẽ có thể cắt bỏ hầu hết các bước và ở lại NativeLand và nhận được hiệu suất gần như giống nhau. Nhưng đây không phải là một sự đảm bảo và nếu một cái gì đó ngăn cản động cơ có thể sử dụng các tối ưu hóa, một số tính ưa thích trong mã của bạn hoặc ghi đè nội trang hoặc vô số vấn đề, thì bạn ngay lập tức thấy kết quả trong hiệu suất. === buộc nó.

=== chỉ là về điều bất biến duy nhất trong Javascript.

+0

Bằng chứng của bạn về vấn đề này ở đâu? Vì '==' và '===' được xác định để hoạt động giống nhau khi các toán hạng cùng loại, tôi không thể tin rằng các môi trường JS sẽ thực hiện chúng khác nhau trong trường hợp đó. –

+0

.... bạn có đọc bất kỳ bài đăng nào của tôi sau câu đầu tiên không? Tôi theo nghĩa đen bao gồm đầu ra V8. Câu trả lời ngắn: == cuộc gọi === đầu tiên và trong trường hợp === là sự thật sự khác biệt là không đáng kể. Ngoài ra == đã mất theo định nghĩa. –

+0

Và chỉ cần lưu ý cho hậu thế. Bằng chứng trên của tôi là một phương pháp mới, tôi có thể xác định người gọi hàm JS bên trong và các toán hạng được định vị chính xác, từ các đối tượng JavaScript tùy ý, trong tất cả các hiện thực sử dụng V8 hoặc JavaScriptCore mà tôi chưa bao giờ thấy ở nơi khác, và trực tiếp cho phép quá tải toán tử trong JS, điều này là không thể và hiện tại không được thực hiện thành công. –

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