Python vs Julia เปรียบเทียบความเร็ว


10

ฉันพยายามเปรียบเทียบตัวอย่างสองอันนี้และดูว่าสามารถทำซ้ำได้กี่วินาทีในหนึ่งวินาที ปรากฎว่า Julia สามารถทำซ้ำได้ 2.5 ล้านครั้งในขณะที่ Python 4 ล้านคน จูเลียน่าจะไม่เร็วกว่านี้หรือ หรืออาจเป็นตัวอย่างข้อมูลทั้งสองนี้ไม่เท่ากัน?

งูหลาม:

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

จูเลีย:

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

4
ฉันไม่แน่ใจว่า Julia ทำงานอย่างไร แต่ดูเหมือนว่าคุณต้องสร้างวัตถุใหม่สำหรับการเปรียบเทียบทุกครั้งในขณะที่ Python ทำการเปรียบเทียบจำนวนเต็มอย่างง่าย
chepner

1
โปรดทราบด้วยว่านี่เป็นการเปรียบเทียบความเร็วของคนจนบางคนใช่ไหม ทุกวันนี้คุณสามารถทำให้ Python และ Julia ทำงานได้อย่างรวดเร็วด้วยความเร็วเดียวกันกับแรงจูงใจที่เหมาะสม (ทั้งสองด้าน) หากคุณกำลังทำสิ่งนี้เพื่อเลือกภาษาใดภาษาหนึ่งให้ดูว่าคุณคิดว่าภาษาใดง่ายกว่า คุณสามารถปรับให้เหมาะสมในภายหลังเมื่อคุณต้องการมัน
norok2

@ norok2 นั่นเป็นความจริงสำหรับบางรหัส แต่ไม่ใช่สำหรับรหัสอื่น ๆ หากคุณสามารถเปลี่ยนรหัส Python ให้เป็นการเรียกไปยังฟังก์ชั่นห้องสมุดที่เขียนด้วยภาษาที่รวดเร็วหรือถ้ามันรองรับโดย numba หรือสิ่งที่คล้ายกันบางทีก็อาจจะเป็นเช่นนั้น แต่ Python จะช้าลงอย่างมาก
DNF

@DNF มีบางสิ่งที่หลามเร็วขึ้นและอีกอันที่ Julia เร็วขึ้น ฉันแน่ใจว่าคุณสามารถหาตัวอย่างของทั้งสอง มันเพิกเฉยต่อภาพรวมที่มากเกินไปที่จะบอกว่า Python นั้น "สำคัญ" (อะไรก็ตามที่อาจหมายถึง) ช้าลงเพียงเพราะการวนลูปและการเรียกฟังก์ชันที่ค่อนข้างแพง แน่นอนว่าถ้านั่นเป็นม้าแข่งของคุณบางทีคุณอาจจะเก่งกว่าจูเลีย อย่างไรก็ตามหากคุณใช้เครื่องมือที่เหมาะสมคุณสามารถใช้ Python ได้อย่างรวดเร็ว มันคุ้มค่าที่จะเรียนรู้เครื่องมือเหล่านี้หรือดีกว่าที่จะเรียนรู้ภาษาอื่น มันยากที่จะพูด
norok2

1
ฉันใช้ทั้งสองภาษาและในขณะที่มีตัวอย่างบางอย่างของทั้งสองที่จะเร็วขึ้นความสมดุลนั้นอยู่ในด้านหนึ่งอย่างมาก มันเป็นเพียงผลลัพธ์ของ Python ที่ถูกตีความและแทบจะไม่ได้เน้นไปที่ประสิทธิภาพเลยในขณะที่ Julia นั้นให้ความสำคัญกับประสิทธิภาพเป็นอย่างมาก จริงๆแล้วมันเหมือนกับบอกว่า Python นั้นเร็วเท่ากับ C มันคงจะแปลกมากถ้าไม่มีความแตกต่างอย่างมีนัยสำคัญและมันจะบ่อนทำลายจุดประสงค์ของจูเลียมาก
DNF

คำตอบ:


9

นี่เป็นการเปรียบเทียบประสิทธิภาพที่แปลกเนื่องจากโดยทั่วไปแล้วจะทำการวัดเวลาที่ใช้ในการคำนวณบางสิ่งบางอย่างของสารแทนที่จะเห็นว่าการทำซ้ำเล็กน้อยสามารถทำได้ในระยะเวลาหนึ่ง ฉันมีปัญหาในการทำให้รหัส Python และ Julia ของคุณทำงานดังนั้นฉันจึงปรับเปลี่ยนรหัส Julia ให้ทำงานและไม่ได้เรียกใช้รหัส Python @chepner ตามที่ระบุไว้ในความคิดเห็นการใช้now()และการเปรียบเทียบเวลากับDateTimeวัตถุนั้นค่อนข้างแพง time.time()ฟังก์ชั่นPython เพียงแค่ส่งกลับค่าจุดลอย เมื่อปรากฎว่ามีฟังก์ชั่น Julia ที่เรียกtime()ว่าทำสิ่งเดียวกัน:

julia> time()
1.587648091474481e9

นี่คือช่วงเวลาของf()ฟังก์ชั่นดั้งเดิมของคุณ(ปรับเปลี่ยนให้ทำงาน) ในระบบของฉัน:

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

มันทำซ้ำเกือบ 5 ล้านครั้งก่อนเวลาจะหมด ดังที่ฉันพูดฉันไม่สามารถรับรหัส Python ของคุณให้ทำงานบนระบบของฉันได้โดยไม่ต้องเล่นซอ (ซึ่งฉันไม่ได้สนใจ) แต่นี่เป็นรุ่นf()ที่ใช้time()แทนซึ่งฉันจะจินตนาการถึงการโทร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

รุ่นนี้มีการทำซ้ำ 36 ล้าน ดังนั้นฉันเดาว่า Julia เร็วขึ้นเมื่อวนลูป? เย้! ที่จริงแล้วงานหลักในลูปนี้คือการโทรไปtime()... จูเลียเร็วกว่าในการสร้างจำนวนมากtime()โทร !

ทำไมมันถึงแปลกเวลานี้ time()ที่ผมกล่าวว่าส่วนใหญ่ของการทำงานที่เกิดขึ้นจริงที่นี่จะเรียก ส่วนที่เหลือของวงไม่ได้ทำอะไรเลย ในภาษาที่คอมไพล์แล้วปรับให้เหมาะสมหากคอมไพเลอร์เห็นลูปที่ไม่ทำอะไรเลยมันจะกำจัดมันอย่างสมบูรณ์ ตัวอย่างเช่น:

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    

ว้าวศูนย์วินาที! เป็นไปได้อย่างไร? ลองดูรหัส LLVM (เช่นรหัสเครื่อง แต่สำหรับเครื่องจินตภาพที่ใช้เป็นสื่อกลาง) สิ่งนี้จะลดลงไปที่:

julia> @code_llvm h()

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

คอมไพเลอร์มองเห็นลูปซึ่งแสดงให้เห็นว่าผลลัพธ์นั้นเหมือนกันทุกครั้งและเพียงแค่ส่งกลับค่าคงที่แทนการดำเนินการลูปจริง ซึ่งแน่นอนต้องใช้เวลาเป็นศูนย์


มันคือBogoMipsของภาษาโปรแกรม
norok2

1
ใช่ แต่ bogomips ใช้สำหรับวัด CPU ไม่ใช่ภาษาโปรแกรม แต่แน่นอนว่ามันเป็นสิ่งที่เราสามารถวัดได้
StefanKarpinski

4

คุณอาจต้องการใช้time_nsฟังก์ชั่นใน Julia:

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

บนคอมพิวเตอร์ของฉันทำงานเร็วกว่า Python 10 เท่า


4

นั่นไม่ใช่สิ่งที่ฉันสังเกตเห็นในระบบของฉัน:

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

แต่โปรดทราบว่าการใช้time(เช่นการเปรียบเทียบหมายเลขธรรมดา) นั้นยังเร็วกว่า:

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

คุณไม่ควรใช้กับtime.perf_counter_ns()Python
norok2

การใช้ time.perf_counter_ns จะไม่เปลี่ยนแปลงสิ่งใด (อย่างน้อยในระบบของฉัน) สำหรับการวัดประสิทธิภาพนี้ ฉันเดาว่าเมื่อการวัดความแตกต่างของเวลาตามลำดับ 1 วินาทีความแม่นยำของการวัดเวลานั้นไม่สำคัญเท่าไหร่ เฉพาะเวลาที่ใช้ในการวัดและเปรียบเทียบวัตถุผลลัพธ์ที่เกิดขึ้นที่นี่ (รวมถึงประสิทธิภาพของลูป)
FrançoisFévotte

ในเวลาการวัดจูเลียมีความสำคัญ - นั่นคือสาเหตุที่รหัสของฉันฉันtime_nsไม่ได้ใช้timeเพราะเร็วกว่า ~ 30%
BogumiłKamiński
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.