So sánh tốc độ giữa Python và Julia


9

Tôi đã thử so sánh hai đoạn trích này và xem có bao nhiêu lần lặp lại có thể được thực hiện trong một giây. Hóa ra Julia đạt được 2,5 triệu lần lặp trong khi Python 4 triệu. Không phải Julia nên nhanh hơn. Hoặc có thể hai đoạn trích này không tương đương?

Con trăn

t1 = time.time()
i = 0
while True:
    i += 1
    if time.time() - t1 >= 1:
        break

Julia:

function f()
    i = 0
    t1 = now()
    while true
        i += 1
        if now() - t1 >= Base.Dates.Millisecond(1000)
            break
        end
    end
    return i
end

4
Tôi không chắc cách Julia hoạt động, nhưng có vẻ như bạn phải xây dựng một đối tượng mới cho mọi so sánh, trong khi Python đang thực hiện các phép so sánh số nguyên đơn giản.
chepner

1
Ngoài ra xin lưu ý rằng đây là một số so sánh tốc độ người đàn ông nghèo, phải không? Ngày nay, bạn có thể khiến Python và Julia chạy với tốc độ tương đương với tốc độ động lực thích hợp (ở cả hai đầu). Nếu bạn đang làm điều này để chọn một trong hai ngôn ngữ, hãy xem ngôn ngữ nào sẽ dễ dàng hơn để bạn suy nghĩ. Bạn có thể tối ưu hóa điều đó sau, khi bạn thực sự cần nó.
norok2

@ norok2 Điều đó đúng với một số mã nhưng không đúng với những mã khác. Nếu bạn có thể biến mã Python thành một cuộc gọi đến chức năng thư viện được viết bằng ngôn ngữ nhanh hoặc nếu được hỗ trợ bởi numba hoặc một cái gì đó tương tự, thì có thể, nhưng nếu không thì Python chậm hơn đáng kể.
DNF

@DNF Có một số điều mà Python nhanh hơn và một số khác là Julia nhanh hơn. Tôi chắc chắn bạn có thể tìm thấy ví dụ của cả hai. Thật quá đáng khi bỏ qua bức tranh hoàn chỉnh để nói rằng Python "đáng kể" (bất cứ điều gì có thể có nghĩa) chậm hơn chỉ vì các lệnh gọi hàm và vòng lặp rõ ràng tương đối đắt tiền. Chắc chắn, nếu đó là con ngựa công việc của bạn hơn có lẽ bạn tốt hơn với Julia. Tuy nhiên, nếu bạn sử dụng đúng công cụ, bạn có thể nhận được nhanh như nhau trong Python. Có đáng để học những công cụ này hay tốt hơn là học một ngôn ngữ khác. Thật khó để nói.
norok2

1
Tôi sử dụng cả hai ngôn ngữ và trong khi có 'một số' ví dụ về cả hai ngôn ngữ nhanh hơn, sự cân bằng đáng kể ở một bên. Nó đơn giản chỉ là hậu quả của việc Python bị giải thích và hầu như không tập trung vào hiệu suất, trong khi Julia tập trung mạnh vào hiệu suất. Nó thực sự rất giống nói rằng Python là nhanh như C. Nó sẽ là rất kỳ quặc nếu có không phải là một sự khác biệt đáng kể, và nó sẽ làm suy yếu nhiều về mục đích của Julia.
DNF

Câu trả lời:


9

Đây là một so sánh hiệu suất kỳ lạ vì thông thường người ta đo thời gian cần thiết để tính toán một thứ gì đó, thay vì xem có bao nhiêu lần lặp lại tầm thường mà người ta có thể làm trong một khoảng thời gian nhất định. Tôi gặp sự cố khi mã Python và Julia của bạn hoạt động, vì vậy tôi đã sửa đổi mã Julia để hoạt động và chỉ không chạy mã Python. Theo ghi nhận của @chepner trong một bình luận, sử dụng now()và thực hiện so sánh thời gian với DateTimecác đối tượng là khá tốn kém. Hàm Python time.time()chỉ trả về giá trị dấu phẩy động. Hóa ra, có một hàm Julia được gọi là time()thực hiện chính xác điều tương tự:

julia> time()
1.587648091474481e9

Đây là thời gian của f()chức năng ban đầu của bạn (được sửa đổi để hoạt động) trên hệ thống của tôi:

julia> using Dates

julia> function f()
           i = 0
           t1 = now()
           while true
               i += 1
               if now() - t1 >= Millisecond(1000)
                   break
               end
           end
           return i
       end
f (generic function with 1 method)

julia> f()
4943739

Nó đã thực hiện gần 5 triệu lần lặp trước khi hết giờ. Như tôi đã nói, tôi không thể có được mã Python của bạn để chạy trên hệ thống của mình mà không gặp khó khăn gì (điều mà tôi không bận tâm làm). Nhưng đây là phiên bản f()sử dụng time()thay thế, mà tôi sẽ gọi một cách tưởng tượng g():

julia> function g()
           i = 0
           t1 = time()
           while true
               i += 1
               if time() - t1 >= 1
                   break
               end
           end
           return i
       end
g (generic function with 1 method)

julia> g()
36087637

Phiên bản này đã làm 36 triệu lần lặp. Vì vậy, tôi đoán Julia là nhanh hơn trong vòng lặp? Yay! Chà, thực ra công việc chính trong vòng lặp này là các cuộc gọi để time()... Julia nhanh hơn trong việc tạo ra nhiều time()cuộc gọi!

Tại sao nó kỳ lạ với thời gian này? Như tôi đã nói, hầu hết các công việc thực tế ở đây là gọi time(). Phần còn lại của vòng lặp không thực sự làm gì cả. Trong một ngôn ngữ được biên dịch tối ưu hóa, nếu trình biên dịch thấy một vòng lặp không làm gì cả, nó sẽ loại bỏ nó hoàn toàn. Ví dụ:

julia> function h()
           t = 0
           for i = 1:100_000_000
               t += i
           end
           return t
       end
h (generic function with 1 method)

julia> h()
5000000050000000

julia> @time h()
  0.000000 seconds
5000000050000000    

Ái chà, không giây! Làm thế nào là có thể? Chà, hãy xem mã LLVM (giống như mã máy nhưng đối với một máy tưởng tượng được sử dụng làm đại diện trung gian) thì điều này hạ thấp xuống:

julia> @code_llvm h()

;  @ REPL[16]:1 within `h'
define i64 @julia_h_293() {
top:
;  @ REPL[16]:6 within `h'
  ret i64 5000000050000000
}

Trình biên dịch nhìn thấy vòng lặp, chỉ ra rằng kết quả là giống nhau mọi lúc và chỉ trả về giá trị không đổi đó thay vì thực sự thực hiện vòng lặp. Mà, tất nhiên, mất không thời gian.


Đó là bogomips các ngôn ngữ lập trình
norok2

1
Phải, nhưng bogomips được sử dụng để đo CPU, không phải ngôn ngữ lập trình. Nhưng chắc chắn, đó là một điều người ta có thể đo lường.
StefanKarpinki

4

Bạn có thể muốn sử dụng time_nschức năng trong Julia:

function f()
    i = 0
    t1 = time_ns()
    while true
        i += 1
        if time_ns() - t1 >= 10^9
            break
        end
    end
    return i
end

Trên máy tính của tôi, nó chạy nhanh hơn 10 lần so với Python.


4

Chà, đó không phải là những gì tôi quan sát được trên hệ thống của mình:

Python 3.7.7

Python 3.7.7 (default, Mar 26 2020, 15:48:22) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.4.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import time                                                                                                                                                       

In [2]: def f(): 
   ...:     t1 = time.time() 
   ...:     i = 0 
   ...:     while True: 
   ...:         i += 1 
   ...:         if time.time() - t1 >= 1: 
   ...:             return i 
   ...:                                                                                                                                                                   

In [3]: f()                                                                                                                                                               
Out[3]: 4676268


Julia 1.4.0:

julia> using Dates

julia> function f()
           i = 0
           t1 = now()
           while true
               i += 1
               if now() - t1 >= Dates.Millisecond(1000)
                   break
               end
           end
           return i
       end
f (generic function with 1 method)

julia> f()
6339528

nhưng lưu ý rằng chỉ cần sử dụng time(tức là so sánh số thường) vẫn nhanh hơn:

julia> function f()
           i = 0
           t1 = time()
           while true
               i += 1
               if time() - t1 >= 1
                   break
               end
           end
           return i
       end
f (generic function with 1 method)

julia> f()
24742703


bạn có nên sử dụng time.perf_counter_ns()Python không?
norok2

Sử dụng time.perf_corer_ns không thay đổi bất cứ điều gì (ít nhất là trên hệ thống của tôi) cho điểm chuẩn này. Tôi đoán rằng, khi đo chênh lệch thời gian theo thứ tự 1 giây, độ chính xác của phép đo thời gian không quan trọng lắm. Chỉ cần thời gian để thực hiện phép đo và so sánh các đối tượng kết quả ở đây (cũng như hiệu quả của các vòng lặp).
François Févotte

Trong Julia đo lường vấn đề thời gian - đó là lý do tại sao trong mã của tôi, tôi time_nskhông sử dụng timevì nó nhanh hơn ~ 30% sau đó.
Bogumił Kamiński
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.