Go での効率的な CSV の読み取りと書き込み
提供されている Go コードでは、CSV の読み取りと書き込みのプロセスが重大なパフォーマンスの問題を引き起こしています。これに対処するために、これらの操作を合理化する代替アプローチを検討してみましょう。
CSV の効率的な読み取り
CSV ファイル全体をメモリにロードして処理する代わりに、一度に 1 行を処理する csv.Reader の機能を利用できます。これにより、メモリ使用量が大幅に削減され、パフォーマンスが向上します。次のコード スニペットは、このアプローチを示しています。
<code class="go">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 <- rec } }() return }</code>
この関数は、io.Reader を入力として受け取り、CSV レコードを表す文字列のスライスを生成するチャネルを返します。
Writing CSV の効率的な
同様に、CSV を書き込む場合、一度に 1 行ずつ書き込む csv.Writer のメソッドを使用してパフォーマンスを向上させることができます。効率的な CSV 書き込みのコードは、CSV 読み取りとほぼ同じです。
<code class="go">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) } } }() }</code>
この関数は、csv.Writer と文字列のスライス (CSV データを表す) を入力として受け取り、データを非同期に書き込みます。
統合
最適化された CSV 読み取りおよび書き込み関数を配置すると、プログラムのメイン ロジックを書き換えて、これらの関数を使用して改善することができます。パフォーマンス:
<code class="go">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() }</code>
この改訂されたコードは、読み取りと書き込みの両方で高いパフォーマンスを維持しながら、CSV ファイルを効率的に読み取り、その場でスコアを計算します。
以上がGo での CSV の読み取りと書き込みを効率化し、パフォーマンスを向上させるにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。