Leitura e gravação eficiente de CSV em Go
No código Go fornecido, o processo de leitura e gravação de CSV está causando problemas significativos de desempenho. Para resolver isso, vamos explorar uma abordagem alternativa que simplifica essas operações.
Lendo CSVs com eficiência
Em vez de carregar o arquivo CSV inteiro na memória e depois processá-lo, nós pode aproveitar a capacidade do csv.Reader de processar uma linha por vez. Isso reduz significativamente o uso de memória e melhora o desempenho. O trecho de código a seguir demonstra essa abordagem:
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 Esta função recebe um io.Reader como entrada e retorna um canal que produz fatias de strings que representam os registros CSV.
Escrevendo CSVs com eficiência
Da mesma forma, para escrever CSVs, podemos usar o método csv.Writer de escrever uma linha por vez para melhorar o desempenho. O código para escrita CSV eficiente é muito semelhante à leitura de 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)
}
}
}()
}
Esta função pega um csv.Writer e uma fatia de fatias de strings (representando os dados CSV) como entradas e grava os dados de forma assíncrona no arquivo CSV.
Integração
Com as funções otimizadas de leitura e gravação de CSV implementadas, a lógica principal do programa pode ser reescrita para usar essas funções para melhorar o desempenho:
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()
}
Este código revisado lê com eficiência o arquivo CSV e calcula pontuações dinamicamente, mantendo alto desempenho tanto para leitura quanto para gravação.
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3