2015-08-28 15 views
10

Tôi đang đọc the Number Type section của sách JavaScript chuyên nghiệp dành cho nhà phát triển web. Dường như tất cả các số ECMAScript là điểm nổi nhị phân64, được chứng thực bởi this MDN article. Nhưng tác giả cuốn sách cũng nói:Số JavaScript, tất cả cùng kích thước trong bộ nhớ?

Vì việc lưu trữ giá trị dấu phẩy động sử dụng gấp đôi bộ nhớ khi lưu trữ giá trị nguyên, ECMAScript luôn tìm cách chuyển đổi giá trị thành số nguyên.

Tôi dự kiến ​​số cho mỗi bộ nhớ sẽ chiếm cùng một lượng bộ nhớ: 64 bit. Và bài viết MDN nói, "Không có loại cụ thể cho số nguyên". Có ai biết tác giả sách có ý nghĩa gì không? Làm thế nào các số nguyên có thể chiếm ít bộ nhớ hơn khi chúng được lưu trữ dưới dạng các phao 64-bit (nếu tôi có quyền đó)? Bạn sẽ tìm thấy toàn bộ phần tại liên kết ở trên (mẫu miễn phí của cuốn sách).

+0

chỉ tối ưu hóa nếu nó có thể. –

+0

Tại sao bạn quan tâm? –

+3

Tại sao bạn quan tâm tại sao tôi quan tâm? – Vimes

Trả lời

7

JavaScript không có bất kỳ loại số nào khác so với điểm nổi chính xác gấp đôi (ngoại trừ trong ECMAScript 6 typed arrays), nhưng triển khai cơ bản có thể chọn lưu trữ các số theo bất kỳ cách nào nó thích miễn là mã JavaScript hoạt động giống nhau .

JavaScript được biên dịch ngày nay, có nghĩa là nó có thể được tối ưu hóa theo nhiều cách không rõ ràng trong ngôn ngữ.

Nếu biến cục bộ trong hàm chỉ nhận giá trị số nguyên và không được tiếp xúc bên ngoài hàm theo bất kỳ cách nào, thì thực tế nó có thể được triển khai bằng kiểu số nguyên khi mã được biên dịch.

Việc triển khai thay đổi trong các trình duyệt khác nhau. Hiện tại có vẻ như tạo nên sự khác biệt lớn trong MS Edge, sự khác biệt lớn trong Firefox và không có sự khác biệt nào trong Chrome: http://jsperf.com/int-vs-double-implementation (Lưu ý: jsperf cho rằng MS Edge là Chrome 42.)


Nghiên cứu sâu hơn:

Các công cụ JS SpiderMonkey (Firefox), V8 (Chrome, Opera), JavaScriptCore (Safari), Chakra (IE) và tê giác (và có thể những người khác, nhưng đó là khó khăn hơn để tìm chi tiết triển khai) sử dụng các cách khác nhau để sử dụng các loại số nguyên hoặc lưu trữ số làm số nguyên khi có thể. Một số trích dẫn:.

"Để có một đại diện hiệu quả các con số và JavaScript đối tượng, V8 đại diện cho cả hai chúng tôi với một giá trị 32 bit Nó sử dụng một chút biết nếu nó là một đối tượng (flag = 1) hoặc một số nguyên (cờ = 0) được gọi là ở đây SMall Integer hoặc SMI vì 31 bit của nó. "

http://thibaultlaurens.github.io/javascript/2013/04/29/how-the-v8-engine-works/

"JavaScript không có một built-in niệm về một giá trị số nguyên, nhưng cho hiệu quả JavaScriptCore sẽ đại diện cho hầu hết các số nguyên như int32 chứ không phải là tăng gấp đôi."

http://trac.webkit.org/wiki/JavaScriptCore

"[...] giá trị phi đôi là một 32-bit loại thẻ và 32-bit tải trọng, đó là bình thường, hoặc một con trỏ hoặc một ký 32-bit số nguyên. "

https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals

"Trong Windows 10 và Microsoft Edge, chúng tôi đã bắt đầu tối ưu hóa phân tích cú pháp Chakra và trình biên dịch JIT để xác định biến const không tờ khai của các số nguyên được định nghĩa toàn cầu và không bao giờ thay đổi trong suốt thời gian thực hiện chương trình. "

https://blogs.windows.com/msedgedev/2015/05/20/delivering-fast-javascript-performance-in-microsoft-edge/

+0

Điều đó có ý nghĩa. Vì vậy, trong các bài kiểm tra JSPerf, chúng tôi giả định rằng nhiều ops/sec là do việc thực thi JavaScript là vật lý sử dụng các số nguyên thay vì phao. Kết quả của Chrome 44 rất lạ: cùng thời gian cho cả hai, nhưng nhanh hơn nhiều so với FireFox. – Vimes

+0

@JVimes: Có, thử nghiệm được thiết kế để ép buộc các số dấu phẩy động cho một trong các mã, nhưng cần phải thử nghiệm thêm để đưa ra bất kỳ kết luận nào về việc liệu điều đó có thực sự xảy ra trong tất cả các trình duyệt hay không. Mục đích là chỉ để cho thấy rằng nó ít nhất tạo nên sự khác biệt, và điều đó khá rõ ràng. – Guffa

3

Không chắc chắn tôi đã hiểu đầy đủ câu hỏi của bạn, nhưng "There is no specific type for integers" có nghĩa là JavaScript không nhận dạng các loại riêng biệt cho số nguyên và phao, nhưng cả hai đều được nhập là Số. Sự phân tách int/float xảy ra "phía sau màn cửa", và đó là ý nghĩa của chúng bằng "ECMAScript always looks for ways to convert values into integers". Điểm mấu chốt là bạn không phải lo lắng về nó, trừ khi bạn cần biến của bạn để bắt chước các số nguyên hoặc phao để sử dụng trong các ngôn ngữ khác, trong trường hợp này có lẽ (tôi đã nói có lẽ?) tốt nhất để chuyển chúng thành chuỗi (vì bạn gặp khó khăn khi vượt qua, giả sử, 5.0 là một float vì JS sẽ chuyển đổi nó thành 5, chính xác vì phần "ECMAScript always looks for ways to convert values into integers").

alert(5.0); // don't expect a float from this

+0

Tôi đã cố làm rõ câu hỏi của mình. Tác giả cho biết mỗi số là một phao 64 bit, nhưng sau đó nói số nguyên chiếm ít bộ nhớ hơn. Vì vậy, tôi bối rối. Bao nhiêu bit là một số nguyên đằng sau màn cửa? – Vimes

+0

Phải, tôi nghĩ rằng bài viết mà @duskwuff đã cho tôi giải thích nó một cách hoàn hảo: http://www.2ality.com/2012/04/number-encoding.html – Shomz

4

Bởi vì lưu trữ các giá trị dấu chấm động sử dụng gấp đôi so với dung lượng bộ nhớ như lưu trữ các giá trị số nguyên, ECMAScript luôn tìm kiếm cách để chuyển đổi giá trị thành số nguyên.

Đoạn này hoàn toàn vô nghĩa. Phớt lờ nó đi!

Số là số. ECMAScript không phân biệt gì giữa các giá trị số dấu phảy động và số nguyên.

Ngay cả trong hầu hết các thời gian chạy JS, tất cả các giá trị số được lưu trữ dưới dạng dấu phẩy động kép chính xác.

+1

Hmmm, bạn có chắc chắn về dòng cuối cùng không? Âm thanh như ** rất nhiều ** bộ nhớ lãng phí. – Shomz

+2

@Shomz Có. Ví dụ, xem: http://www.2ality.com/2012/04/number-encoding.html Hãy nhớ rằng chi phí lưu trữ trong một bộ nhớ là đáng kể hơn 32 bit anyway; tiết kiệm từ việc sử dụng loại dữ liệu nhỏ hơn sẽ là tối thiểu. :) – duskwuff

+0

Rất thú vị, cảm ơn bạn đã liên kết và giải thích. Một upvote từ tôi. – Shomz

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