Go中高效率的CSV讀寫
在提供的Go程式碼中,CSV讀寫過程導致了嚴重的效能問題。為了解決這個問題,讓我們來探索一種簡化這些操作的替代方法。
高效讀取 CSV
我們不是將整個 CSV 檔案載入到記憶體然後處理,而是可以利用 csv.Reader 一次處理一行的能力。這顯著減少了記憶體使用並提高了效能。以下程式碼片段示範了這個方法:
func processCSV(rc io.Reader) (ch chan []string) {
ch = make(chan []string, 10)
go func() {
r := csv.NewReader(rc)
if _, err := r.Read(); err != nil { //read header
log.Fatal(err)
}
defer close(ch)
for {
rec, err := r.Read()
if err != nil {
if err == io.EOF {
break
}
log.Fatal(err)
}
ch 此函數採用 io.Reader 作為輸入,並傳回一個通道,該通道產生表示 CSV 記錄的字串切片。
高效寫入 CSV
同樣,對於寫入CSV,我們可以使用csv.Writer的一次寫入一行的方法來提高效能。高效率 CSV 寫入的程式碼與 CSV 讀取大致相似:
func writeCSV(wc *csv.Writer, data [][]string) {
go func() {
defer wc.Flush(nil)
for _, rec := range data {
if err := wc.Write(rec); err != nil {
log.Fatal(err)
}
}
}()
}
此函數採用 csv.Writer 和字串切片(表示 CSV 資料)作為輸入,並將資料非同步寫入 CSV 檔案。
Integration
優化了CSV 讀寫功能後,可以重寫程式的主要邏輯,使用這些功能來提高效能:
func main() {
recordsCh := processCSV(os.Open("./path/to/datafile.csv"))
outfile, err := os.Create("./where/to/write/resultsfile.csv"))
if err != nil {
log.Fatal("Unable to open output")
}
defer outfile.Close()
writer := csv.NewWriter(outfile)
writer.Write([]string{"time", "value", "score"})
for record := range recordsCh {
time := record[0]
value := record[1]
// calculate scores; THIS EXTERNAL METHOD CANNOT BE CHANGED
score := calculateStuff(value)
valueString := strconv.FormatFloat(floatValue, 'f', 8, 64)
scoreString := strconv.FormatFloat(prob, 'f', 8, 64)
writer.Write([]string{time, valueString, scoreString})
}
writer.Flush()
}
此修訂後的程式碼可有效讀取 CSV 檔案並動態運算分數,同時保持讀寫的高效能。
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3