1

I'm trying to marshal an array into a string, separating all elements with newlines. I'm running out of memory and think about a more efficient way to do this.

buffer := ""
for _, record := range all_data {

    body, _ := json.Marshal(record)
    buffer += string(body) + "\n" // i run out of memory here

Question:

Is there a way to append a newline character to a byte array? Right now I'm casting via string(body), but I think that this operation allocates a lot of memory (but maybe I'm wrong).

Rene Knop
  • 1,788
  • 3
  • 15
  • 27
K2xL
  • 9,730
  • 18
  • 64
  • 101

2 Answers2

4

Assuming your data isn't inherently too big for the computer it's running on, the problem is likely the inefficient building of that string. Instead you should be using a bytes.buffer and then callings it's String() method. Here's an example;

var buffer bytes.Buffer

for _, record := range all_data {
    body, _ := json.Marshal(record)
    buffer.Write(body)
    buffer.WriteString("\n")
}

fmt.Println(buffer.String())
evanmcdonnal
  • 46,131
  • 16
  • 104
  • 115
  • Heh, I was just about to post this as I just changed my code to use bytes.Buffer. Thanks! – K2xL Aug 03 '15 at 16:28
0

To add to evanmcdonnal's answer: you don't even need an intermediate buffer created by json.Marshal:

var buf bytes.Buffer
enc := json.NewEncoder(&buf)
for _, record := range allData {
  if err := enc.Encode(record); enc != nil {
    // handle error
  }
  buf.WriteString("\n") // optional
}
fmt.Println(buf.String())

https://play.golang.org/p/5K9Oj0Xbjaa

abbot
  • 27,408
  • 6
  • 54
  • 57