ホームページ  >  記事  >  バックエンド開発  >  同時実行を使用して Go で CSV ファイルを効率的に読み書きするにはどうすればよいですか?

同時実行を使用して Go で CSV ファイルを効率的に読み書きするにはどうすればよいですか?

DDD
DDDオリジナル
2024-11-02 20:40:03223ブラウズ

How can I efficiently read and write CSV files in Go using concurrency?

Go での効率的な CSV 読み取りおよび書き込み

Go で CSV ファイルを効率的に読み取りおよび書き込みするタスクには、I/O 操作の最適化が含まれます。 CSV ファイルを読み取り、データに対して計算を実行し、結果を新しい CSV ファイルに書き込む次のコード スニペットを考えてみましょう:

<code class="go">package main

import (
  "encoding/csv"
  "fmt"
  "log"
  "os"
  "strconv"
)

func ReadRow(r *csv.Reader) (map[string]string, error) {
  record, err := r.Read()
  if err == io.EOF {
    return nil, io.EOF
  }
  if err != nil {
      return nil, err
  }
  m := make(map[string]string)
  for i, v := range record {
    m[strconv.Itoa(i)] = v
  }
  return m, nil
}

func main() {
  // load data csv
  csvFile, err := os.Open("./path/to/datafile.csv")
  if err != nil {
    log.Fatal(err)
  }
  defer csvFile.Close()

  // create channel to process rows concurrently
  recCh := make(chan map[string]string, 10)
  go func() {
    defer close(recCh)
    r := csv.NewReader(csvFile)
    if _, err := r.Read(); err != nil { //read header
        log.Fatal(err)
    }

    for {
        rec, err := ReadRow(r)
        if err == io.EOF {
          return  // no more rows to read
        }
        if err != nil {
          log.Fatal(err)
        }
        recCh <- rec
    }
  }()

  // write results to a new 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)

  for record := range recCh {
    time := record["0"]
    value := record["1"]

    // get float values
    floatValue, err := strconv.ParseFloat(value, 64)
    if err != nil {
      log.Fatal("Record: %v, Error: %v", floatValue, err)
    }

    // calculate scores; THIS EXTERNAL METHOD CANNOT BE CHANGED
    score := calculateStuff(floatValue)

    valueString := strconv.FormatFloat(floatValue, 'f', 8, 64)
    scoreString := strconv.FormatFloat(prob, 'f', 8, 64)
    //fmt.Printf("Result: %v\n", []string{time, valueString, scoreString})

    writer.Write([]string{time, valueString, scoreString})
  }

  writer.Flush()
}</code>

このコードの主な改善点は、CSV を処理するために同時実行性を使用していることです。一度に 1 行ずつ。チャネルを使用すると、ゴルーチンで入力 CSV ファイルから行を読み取り、その結果をメイン ルーチンで出力 CSV ファイルに同時に書き込むことができます。このアプローチにより、ファイル全体がメモリに読み込まれることが回避されるため、メモリ消費量が大幅に削減され、パフォーマンスが向上します。

以上が同時実行を使用して Go で CSV ファイルを効率的に読み書きするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。