iT邦幫忙

2024 iThome 鐵人賽

DAY 28
0
Python

上次介紹的棒球套件很少更新了,那就只好自己寫一個!?系列 第 28

Day 28 - 簡單使用 timeit 測試程式執行時間與 requests.Session() 增加效能

  • 分享至 

  • xImage
  •  

昨天我們把另一項功能 minor_statcast_search 也完成了,因為大致上跟我一開始想要的功能都差不多完成了,今天就會來看能不能把這些 functions 進行最佳化。

timeit

首先我們在寫 Python 的時候,會用他們的一個內建套件 timeit 來進行效能的測試。基本有兩個用法,一個是在終端機(Command Line)直接執行 python -m timeit "{想要測試的程式}",在剛剛提供的文章也有提供一些範例,這通常在測試只需一行就能寫完的程式碼,可以很快地做測試。我也有在自己的電腦做測試。
https://ithelp.ithome.com.tw/upload/images/20241012/20163024g3rG046RUV.png

可以看到執行完會顯示 20000 loops, best of 5: 13 usec per loop,這句的意思是說,執行了我們提供的程式 20000 次,取了表現最好的 5 次後,平均花費的時間為 13 usec。20000 跟 5 都是預設值,之後我們可以進行一些操作進行更改。

另外一種方法,就是直接寫在 .py 裡面後,使用 print 或是其他 logger 查看結果。

from timeit import timeit

print(timeit('"-".join(str(n) for n in range(100))', number=10000))
# 0.3763910260000216
print(timeit('"-".join([str(n) for n in range(100)])', number=10000))
# 0.32127862900000537
print(timeit('"-".join(map(str, range(100)))', number=10000))
# 0.26695608499994705

執行出來的是秒數,number 則是執行的次數。不過這些都是直接用字串描述程式碼的部分,如果是要測試我們寫的 function 的話,可以使用 globals 參數,像我這邊是寫在 example.py 裡的 example() 進行測試,就可以寫成:

from timeit import timeit
from src.baseball_stats_python import statcast_search


def example():
    df = statcast_pitcher_search(
        pitchers_lookup="808967")

benchmark = timeit("example()", globals=globals(), number=10)
print(f'Statcast Search: {benchmark} seconds')

這樣就會執行 10 次算平均,記得要用字串來寫 example()。從提供的文章裡面,也有其他的參數可以進行調整,大家可以去玩玩看。

requests.Session

我們在取得 Statcast 資料的時候,是透過 requests 傳入 API Url 來從他們的 Server 取得資料,但如果我們想重複使用相同的 params 取得資料,使用 requests.get 話每次都會重新建立一個 connection,這樣重複的建立與關閉 connection 就會增加執行的時間。我們可以使用一樣是 Python 的 logging 套件。簡單來說這個套件可以讓幫助我們的訊息有更豐富的資訊,也能透過他們提供的項目像是 INFODEBUGERROR 等項目來分類訊息,會比單單只使用 print 還讓人更清楚。requests 也有使用 logging ,他們會在 requests 送出的時候,同時提供 DEBUG 類別的訊息,我們可以透過 basicConfi() 來打開顯示。

import logging
logging.basicConfig(level=logging.DEBUG)

然後我們再執行 timeit,就會看到顯示十次 DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): baseballsavant.mlb.com:443,這就代表每次都會開啟一個新的 connection。如果想使用重複的 connection 的話,就會用到一樣是 requestsrequests.Session,他會建立一個 Session 讓 connection 可以共用,之後再把我們原本的 requests.get 改成 session.get

import requests
import logging

session = requests.Session()

- requests.get("https://...")
+ session.get("https://...")

這樣重新執行 timeit 後,就會發現只會執行第一次 DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): baseballsavant.mlb.com:443,成功減少建立 connection 的次數,達到改善效能的效果。可以參考: Session Objects

本日小結

今天簡單介紹了一下怎麼測試效能,跟一個可以立即改善 requests 的方法,其實還有可以使用第三方套件 requests-cache,大家也可以試試看。明天可能會再更詳細介紹 logging

感謝大家耐心地看完這篇文章,有任何問題與建議歡迎留言告訴我,明天見,掰掰。


上一篇
Day 27 - Minor Statcast Search
下一篇
Day 29 - 使用 logging 顯示更多訊息給使用者
系列文
上次介紹的棒球套件很少更新了,那就只好自己寫一個!?31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言