Heim  >  Artikel  >  Backend-Entwicklung  >  Wie kann ich CSV-Dateien in Go mithilfe der Parallelität effizient lesen und schreiben?

Wie kann ich CSV-Dateien in Go mithilfe der Parallelität effizient lesen und schreiben?

DDD
DDDOriginal
2024-11-02 20:40:03223Durchsuche

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

Effizientes CSV-Lesen und Schreiben in Go

Die Aufgabe, eine CSV-Datei effizient in Go zu lesen und zu schreiben, beinhaltet die Optimierung der E/A-Vorgänge . Betrachten Sie den folgenden Codeausschnitt, der eine CSV-Datei liest, Berechnungen an den Daten durchführt und die Ergebnisse in eine neue CSV-Datei schreibt:

<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>

Die wichtigste Verbesserung in diesem Code ist die Verwendung von Parallelität zur Verarbeitung von CSV Zeilen nacheinander. Mithilfe eines Kanals können wir Zeilen aus der Eingabe-CSV-Datei in einer Goroutine lesen und die Ergebnisse gleichzeitig in die Ausgabe-CSV-Datei in der Hauptroutine schreiben. Dieser Ansatz vermeidet das Laden der gesamten Datei in den Speicher, was den Speicherverbrauch erheblich reduzieren und die Leistung verbessern kann.

Das obige ist der detaillierte Inhalt vonWie kann ich CSV-Dateien in Go mithilfe der Parallelität effizient lesen und schreiben?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn