การพัฒนาซอฟแวร์ไม่ว่าจะด้วยภาษาอะไรก็ตาม องค์ประกอบหนึ่งที่ขาดไม่ได้เลยคือเรื่องของประสิทธิภาพหรือความเร็วในการทำงานของซอฟแวร์ ในภาษา Python เองก็มีโมดูล (module) ที่ให้นักพัฒนาได้เลือกใช้เพื่อวัดประสิทธิภาพของซอฟแวร์อยู่หลากหลายเหมือนกัน ซึ่งหนึ่งในนั้นก็คือ timeit
timeit เป็นโมดูลที่ติดมา (built-in) กับภาษา Python เลย ที่ช่วยให้เราวัดประสิทธิภาพการทำงานของโค้ดด้วยการวัดเวลาที่ใช้ในการประมวลผล (execution time) สามารถใช้งานผ่าน Command-line Interface (CLI) หรือเรียกใช้งาน (callable) ในรูปแบบฟังก์ชันก็ได้
บางคนอาจจะบอกว่า ใช้โมดูล time ไปเลยจะไม่ง่ายกว่าเหรอ ลองเปิดใจแล้วศึกษา timeit ดูก่อนแล้วค่อยตัดสินใจอีกทีก็ได้ครับ ^^
มาดูตัวอย่างการใช้งานผ่าน Command-line Interface กันก่อน
$ python3 -m timeit '"-".join(str(n) for n in range(100))'
10000 loops, best of 3: 22.2 usec per loop
$ python3 -m timeit '"-".join(map(str, range(100)))'
100000 loops, best of 3: 14.8 usec per loop
จากตัวอย่างจะเห็นว่าการใช้งาน map ฟังก์ชันมีประสิทธิภาพที่ดีกว่า
ตัวอย่างการใช้งานแบบฟังก์ชัน
>>> import timeit
>>> timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)
0.2313945009955205
>>> timeit.timeit('"-".join(map(str, range(100)))', number=10000)
0.16620492900256068
กรณีที่อยากใช้กับโค้ดที่มีหลายบรรทัดการใช้งานผ่าน CLI อาจจะยากกว่าการใช้งานแบบฟังก์ชัน เพราะต้องใส่ indent ให้ถูกต้องด้วย
$ python3 -m timeit -s 's="abcdef"' 'if s.startswith("a"):' ' pass'
10000000 loops, best of 3: 0.139 usec per loop
$ python3 -m timeit -s 's="abcdef"' 'if s[0]=="a":' ' pass'
10000000 loops, best of 3: 0.0523 usec per loop
แบบเรียกฟังก์ชันจะง่ายกว่าเพราะเราจะเห็น indent ชัดเจน
>>> import timeit
>>> stmt="""
... if s.startswith('a'):
... pass
... """
>>> timeit.timeit(stmt=stmt, setup='s="abcdefg"')
0.15442462399369106
>>> stmt="""
... if s[0] == 'a':
... pass
... """
>>> timeit.timeit(stmt=stmt, setup='s="abcdefg"')
0.05347593000624329
การใช้งานเพื่อวัดประสิทธิภาพของฟังก์ชัน เราจะต้องเพิ่มการ import function ผ่านพารามิเตอร์ setup
def simple_func():
...
if __name__ == '__main__':
import timeit
print(timeit.timeit("simple_func()", setup="from __main__ import simple_func"))
ข้อควรระวัง
timeit จะปิดการทำงานของ garbage collection เป็นค่าเริ่มต้น เพื่อไม่ให้การวัดผลขึ้นอยู่กับ GC ดังนั้นหากต้องการเปิดใช้งาน GC ด้วยก็สามารถทำได้โดยการเปิดใช้งานผ่านพารามิเตอร์ setup
$ python3 -m timeit -s 's="abcdef"; gc.enable()' 'if s[0]=="a":' ' pass'