Điều gì gây khó khăn cho việc tăng tốc các ngôn ngữ được nhập động khi so sánh với các ngôn ngữ được nhập tĩnh. Nói cách khác, tài sản vốn có của các ngôn ngữ được nhập tĩnh là gì khiến chúng dễ dàng tối ưu hóa cho tốc độ thực thi?Tại sao các ngôn ngữ động được gõ chậm?
Trả lời
Khi truy cập thuộc tính/phương pháp bằng ngôn ngữ được nhập tĩnh, tra cứu thường có thể được giảm xuống địa chỉ hàm tĩnh. Ngay cả trong trường hợp của các phương pháp ảo, mà là chậm hơn, tra cứu chỉ là đọc một bù đắp từ một vtable.
Trong ngôn ngữ động, tên được dựa trên chuỗi. Muốn tìm kiếm foo.bar
? Tìm foo
trong bảng băm biến cục bộ, sau đó tìm bar
trong bảng băm của foo
. Trong một số ngôn ngữ động, như Python và Ruby, có thể có các cuộc gọi tra cứu/phương thức bổ sung để triển khai các thuộc tính được tạo động.
Tất cả các tra cứu này là rất khó để thực hiện nhanh chóng. Python có một trong những triển khai bảng băm được điều chỉnh tốt nhất trên thế giới, và JavaScript đã có hàng triệu đô la tiền nghiên cứu đổ vào làm cho nó nhanh chóng. Những chiến thuật này hoạt động - so sánh JavaScript của Chrome với IE 5 để xem chỉ bao nhiêu - nhưng chúng nhiều, khó khăn hơn nhiều so với việc chỉ tạo các cuộc gọi hàm tĩnh.
Tôi nên đề cập đến cách ngôn ngữ "động" có thể thay đổi. Python có nhiều cách khác nhau để tương tác với các tra cứu biến, điều này rất tốt trong một số trường hợp, nhưng làm cho việc tối ưu hóa rất khó. Các ngôn ngữ động khác, chẳng hạn như Common Lisp và Smalltalk, có thể cạnh tranh đồng đều với các ngôn ngữ tĩnh trong nhiều trường hợp sử dụng vì tra cứu động/sửa đổi được kiểm soát nhiều hơn.
Đó là vì ngôn ngữ được nhập tĩnh thường được biên dịch thành mã máy trong khi ngôn ngữ được nhập động được trong hầu hết các trường hợp do một thông dịch viên điều hành.
Dường như quá đơn giản hóa một chút. Không phải tất cả các ngôn ngữ được nhập tĩnh đều được biên dịch thành mã máy, bao gồm bất kỳ ngôn ngữ CLR hoặc ngôn ngữ JVM tĩnh nào. Không phải tất cả các ngôn ngữ được gõ động được diễn giải, ví dụ nhiều Lisps có thể được biên dịch xuống bytecode, và có nhiều trình biên dịch cho Python và PHP. – Juliet
Lisp thường có thể được biên dịch thành mã máy. –
Hầu hết các triển khai tốt của Lisp thường được biên dịch thành mã máy. Một số không có thông dịch viên, họ chỉ làm biên dịch JIT. –
Một số loại tối ưu hóa thời gian biên dịch chỉ có thể được thực hiện nếu loại chính xác của biến được biết.
Ngôn ngữ được nhập động cũng thường có thêm logic để xác định loại và để đảm bảo rằng giá trị là chính xác cho loại.
Nhìn vào ví dụ python này:
def fact(n):
if n==0:
return n
return n*fact(n-1)
n là gì? Nó là một con số? Nó là một String? Đây có phải là lớp bạn đã xác định trước đó không? Không có cách nào cho trình biên dịch biết đầu vào sẽ nhận được gì. Bạn phải làm rất nhiều kiểm tra tại thời gian chạy, có nghĩa là bạn đang làm nhiều công việc tiềm ẩn cho các hoạt động đơn giản.
Trên thực tế một số languagse, như Ocaml, F # và Haskell hỗ trợ kiểu suy luận (http://en.wikipedia.org/wiki/Type_inference), do đó trình biên dịch có thể xác định kiểu dữ liệu của biến dựa trên cách sử dụng của nó mà không có chú thích kiểu . Ví dụ, 'n == 0', một phép kiểm tra bình đẳng cho một số nguyên nghĩa là 'n' là một số nguyên. Vì trình biên dịch biết 'n' là một số nguyên, nên 'return n' hàm ý hàm trả về một số nguyên. Vì vậy, chúng ta có thể xác định rằng hàm lấy một int và trả về một int. – Juliet
@ Công chúa: Ah, nhưng đó là một máy tính có kích thước int hoặc một bignum? Bạn vẫn phải kiểm tra điều này (nhưng nó có thể được thực hiện hiệu quả) – simon
Bạn vẫn nghĩ quá tĩnh - cách biên dịch lại động và đặc tả (đọc các bài báo tự). Trên thực tế, bằng cách có thông tin kiểu thực tế xung quanh, một trình biên dịch động thậm chí có thể tạo mã nhanh hơn trình biên dịch tĩnh, vì nó thậm chí có thể biết về các dãy giá trị vv. nhanh chóng ... – blabla999
Ngôn ngữ được nhập động phải làm cho tất cả các kiểm tra của họ trong thời gian chạy vì loại có thể thay đổi trong quá trình thực thi.
Ngôn ngữ được nhập tĩnh giải quyết tất cả các loại trong thời gian biên dịch để chi phí được tiêu thụ trước, một lần.
Đây là lý do chính khiến ngôn ngữ nhập động thường chậm hơn. Nhưng có những thứ khác để suy nghĩ. Rất nhiều phụ thuộc vào trình biên dịch hoặc thông dịch viên, việc thực hiện GC, bố trí bảng công văn và các thuật toán tra cứu cùng với các tối ưu hóa khác.
Tất cả phụ thuộc vào việc triển khai: Ngôn ngữ được nhập động có thể nhanh hơn ngôn ngữ được biên dịch, nó chỉ mất nhiều công sức hơn để thực hiện việc này.
Có thể biên dịch các ngôn ngữ động ;-) – Ponkadoodle
Bạn có nghĩa là thực thi rất tốt ngôn ngữ được nhập động có thể nhanh hơn việc thực thi rất kém ngôn ngữ được gõ tĩnh. Ví dụ: – niagr
Câu hỏi của bạn hơi lệch vì ngôn ngữ được nhập động thực sự không chậm. Nhiều ví dụ có thể là trong thực tế, nhưng các ví dụ khác là nhanh (nơi nhanh có nghĩa là "có thể so sánh hợp lý với c" hoặc một cái gì đó tương tự, cf lisp chung).
Nhiều ngôn ngữ động đang chạy trên máy ảo hoặc thậm chí được diễn giải, điều này có thể gây ra sự chậm trễ có thể tránh được. Ở một mức độ nhất định, có các tối ưu hóa có sẵn cho các trình biên dịch ngôn ngữ tĩnh (hoặc các trình động mà đã thực hiện đúng các lời hứa không phải là năng động về điều gì đó) mà không thể có trong một tình huống hoàn toàn năng động.
Tuy nhiên, nếu bạn đang suy nghĩ về sự khác biệt giữa say, python và C++ chẳng hạn, nó không phải là động so với tĩnh thực sự là vấn đề.
Cũng có thể lưu ý rằng một số trình dịch Javascript bytecode gần đây thường hoạt động nhanh như C++. – eyelidlessness
- 1. C# Ngôn ngữ được gõ động
- 2. Tại sao một số ngôn ngữ lập trình nhanh hơn các ngôn ngữ khác?
- 3. Có ngôn ngữ gõ vịt tĩnh nào không?
- 4. Intellisense cho các ngôn ngữ động
- 5. động Hầu hết các ngôn ngữ lập trình năng động
- 6. Tại sao Java được an toàn so với các ngôn ngữ lập trình khác?
- 7. Có một thuật ngữ cho khái niệm này, và nó tồn tại trong một ngôn ngữ gõ tĩnh?
- 8. Tại sao các chuỗi không thay đổi được bằng nhiều ngôn ngữ lập trình?
- 9. Tại sao không đặt ngôn ngữ sửa lỗi UnicodeError này?
- 10. Tại sao hầu như tất cả các ngôn ngữ OO được biên dịch sang bytecode?
- 11. Tại sao thời gian khởi động IronPython quá chậm?
- 12. Tại sao không gõ suy luận hoạt động ở đây?
- 13. Sử dụng cho cả hai ngôn ngữ gõ mạnh tĩnh như Haskell và các ngôn ngữ động (mạnh) như Common LIsp
- 14. Tại sao Android có cách riêng để có được ngôn ngữ hiện tại?
- 15. Tại sao có quá nhiều ngôn ngữ web được giải thích thay vì được biên dịch?
- 16. Tại sao GWT bỏ qua ngôn ngữ trình duyệt?
- 17. Giao diện bằng ngôn ngữ động?
- 18. Tại sao ngôn ngữ Python không có phương thức writeln()?
- 19. Tại sao mọi thứ trong Windows API được gõ?
- 20. Sự khác biệt giữa các ngôn ngữ gõ mạnh và yếu?
- 21. @login_required đang mất ngôn ngữ được chỉ định hiện tại
- 22. Đa ngôn ngữ Ngôn ngữ
- 23. Chức năng sao chép các mảng bằng ngôn ngữ Go
- 24. Tại sao các điểm chậm lại
- 25. ngôn ngữ hoàn toàn được suy ra là gì? và hạn chế của ngôn ngữ đó?
- 26. Tại sao Function.prototype.bind chậm?
- 27. javascript và các ngôn ngữ kịch bản tương tự có được lợi từ việc gõ mạnh không?
- 28. Chọn ngôn ngữ được nhúng
- 29. Tại sao đa thừa kế không được hỗ trợ trong hầu hết ngôn ngữ lập trình?
- 30. Tại sao ngôn ngữ oop không có công cụ sửa đổi truy cập 'chỉ đọc'?
Có thể chỉ định các kiểu tĩnh trong Common Lisp, khi bạn cảm thấy cần thiết. Việc triển khai xây dựng cho tốc độ có thể tạo ra mã rất nhanh. –