我有一個學校作業,我的任務是用 Python 撰寫一個 apache 日志決議器。此決議器將使用 Regex 提取所有 IP 地址和所有 HTTP 方法,并將它們存盤在嵌套字典中。代碼如下:
def aggregatelog(filename):
keyvaluepairscounter = {"IP":{}, "HTTP":{}}
with open(filename, "r") as file:
for line in file:
result = search(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s*.*"(\b[A-Z] \b)', line).groups() #Combines the regexes: IP (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) and HTTP Method ("(\b[A-Z] \b))
if result[0] in set(keyvaluepairscounter["IP"].keys()): #Using set will lower look up time complexity from O(n) to O(1)
keyvaluepairscounter["IP"][result[0]] = 1
else:
keyvaluepairscounter["IP"][result[0]] = 1
if result[1] in set(keyvaluepairscounter["HTTP"].keys()):
keyvaluepairscounter["HTTP"][result[1]] = 1
else:
keyvaluepairscounter["HTTP"][result[1]] = 1
return keyvaluepairscounter
此代碼有效(它為我們提供了日志檔案的預期資料)。但是,當從大型日志檔案(在我的情況下,大約 500 MB)中提取資料時,程式非常慢(腳本需要大約 30 分鐘才能完成)。根據我的老師的說法,一個好的腳本應該能夠在 3 分鐘內處理大檔案(wth?)。我的問題是:我能做些什么來加快我的腳本速度嗎?我做了一些事情,比如用具有更好查找時間的集合替換串列。
uj5u.com熱心網友回復:
至少,在回圈之前預編譯你的正則運算式,即
pattern = re.compile(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s*.*"(\b[A-Z] \b)')
然后在你的回圈中:
for line in file:
result = search(pattern, line).groups()
您還應該考慮優化您的模式,尤其是.*因為它是一項昂貴的操作
uj5u.com熱心網友回復:
我找到了我的答案。使用“re.findall()”而不是將回傳的正則運算式資料存盤在陣列中,如下所示:
for data in re.findall(pattern, text):
do things
代替
array = re.findall(pattern, text)
for data in array:
do things
我還一口氣閱讀了整個檔案:
file = open("file", "r")
text = file.read()
此實作在 1 分鐘內處理了檔案!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/466547.html
上一篇:AsyncProfiler-無法在JMH基準運行程式中加載分析器
下一篇:大型矩陣線性組合的C 性能優化?
