php小編蘋果在Go語言中,我們經常需要處理大型文字檔。有時,我們只對包含特定模式的行感興趣,而忽略其他行。幸運的是,在Go中,我們可以使用正規表示式和bufio.Scanner來實現這個目標。透過使用正規表示式來匹配行,並透過Scanner來逐行處理文件,我們可以輕鬆地過濾掉我們不感興趣的行。這個技巧不僅可以提高效率,還可以讓我們的程式碼更加簡潔和可讀。接下來,讓我們一起來看看如何在Go中實作忽略長文字檔案中包含模式的行。
我正在嘗試實作一個函數來忽略 go 中長文字檔案(保證 ascii)中包含模式的行
我在withoutignore
和withignore
下面的函數都接受檔名參數輸入並傳回*byte.buffer
,隨後可用於寫入 io.writer
。
withignore
函數採用附加參數 pattern
從檔案中排除包含模式的行。該函數可以工作,但通過基準測試,發現它比 慢 5 倍而不忽略
。有什麼辦法可以改進嗎?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
|
基準測試
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
並且可以在命令列中使用“base64dump.log”產生
1 |
|
由於ascii是有保證的,所以可以直接在byte
層級工作。
不過,如果在讀取輸入時檢查每個位元組是否有換行符,然後再次在行內搜尋模式,則操作將應用於每個位元組。
另一方面,如果讀取輸入區塊並對文字中的模式執行最佳化搜索,甚至不檢查每個輸入字節,則可以最大限度地減少每個輸入位元組的操作。
例如,boyer-moore 字串搜尋演算法。 go內建的bytes.index
函數也進行了最佳化。所達到的速度當然取決於輸入資料和實際模式。對於問題中指定的輸入,測量時`bytes.index 的性能顯著提高。
程式
bytes.index
的幫助下,您可以找到該模式在區塊中出現的位置值得注意
讀取操作傳回的資料可能少於區塊大小,因此重複讀取操作直到讀取區塊大小的資料是有意義的。
基準
優化後的程式碼通常要複雜得多,但效能也明顯更好,我們稍後會看到。
1 2 3 |
|
這裡,優化後的程式碼benchmarktestfilter-8
只比沒有過濾的操作慢1.9倍左右,而benchmarktestwithignore-8
方法比沒有過濾的比較值慢5.4倍。
從另一個角度來看:優化後的程式碼比未優化的程式碼快2.8 倍。
程式碼
當然,這是您自己測試的程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
|
基準部分可能看起來像這樣:
1 2 3 4 5 6 7 8 |
|
濾波器函數被拆分,實際工作在 func filter(reader io.reader,pattern []byte, chunksize int) (*bytes.buffer, error)
中完成。
透過注入讀取器和 chunksize,已經準備或考慮了單元測試的創建,這裡缺少這一點,但在處理索引時絕對建議這樣做。
但是,這裡的要點是找到一種方法來顯著提高效能。
以上是在 Go 中忽略長文字檔案中包含模式的行的詳細內容。更多資訊請關注PHP中文網其他相關文章!