3

what is the most efficient way to export array elements into a .csv excel file? Now I am doing like this, but it is very slow. Thank you for all your support.

int FrameWidth = 640;
int FrameHeight = 480;
Int16[] Values;  // 640 x 480, 307200 elements

/*
.. processing ...... 
*/

//Exporting Values to .csv file
string string2csv = null;
for (int y = 0; y < FrameHeight; y++)
{
    for (int x = 0; x < FrameWidth; x++)
    {
        string2csv = string2csv + Values[y * FrameWidth + x] + ";";
    }
    string2csv = string2csv + "\n";
}
File.WriteAllText("string2csv.csv", string2csv);
4
  • 3
    One option would be to use StringBuilder instead of +. Commented Feb 9, 2016 at 21:45
  • 1
    Use the String.Join Method more information here Commented Feb 9, 2016 at 21:46
  • @DriesVB Note that String.Join uses a StringBuilder internally. Commented Feb 9, 2016 at 21:48
  • 2
    Don't do it by hand. Use a library like CSV Helper... Commented Feb 9, 2016 at 21:49

2 Answers 2

3

One alternative is to combine File.WriteAllLines and string.Join;

File.WriteAllLines ("test.txt", 
    Values.Select((x,i) => new {x, i})
          .GroupBy(x => x.i / FrameWidth)
          .Select(grp => string.Join(";", grp.Select(y => y.x)))
);

It will select all elements along with the index in the array.
It will then group the values by row (calculated by dividing the index by the number of columns).
The grouped values are then joined using ; into a string per row, and the rows are all fed into File.WriteAllLines.

Sign up to request clarification or add additional context in comments.

1 Comment

StringBuilder seams to be the fastest, with 27ms, then Joachim's with 38ms, my solution 21 496ms :) I am very very thankful for all your comments! You guys are all great!
2

"most efficient" wil take trial and error, but one easy alternative is to use StringBuilder:

StringBuilder string2csv = new StringBuilder();
for (int y = 0; y < FrameHeight; y++)
{
    for (int x = 0; x < FrameWidth; x++)
    {
        string2csv.Append(Values[y * FrameWidth + x] + ";");
    }
    string2csv.Append("\n");
}

Adding strings using + allocates memory for a new string, then copies the contents of the two strings into the new memory. StringBuilder pre-allocates a buffer in memory and adds characters to the buffer, extending it as necessary. There's much less memory allocation and copying when adding lots of strings.

That may be "fast enough". Other than that, you'd need to get a decent profiler to see where your code is spending the most time and attack that part. It's entirely possible that your "processing..." block is the bottleneck, not the CSV output.

12 Comments

You don't even need to do that. He's building up a string of the contents of the file when he could just write to the file directly.
@JeffMercado Not sure that would be more efficient
For the purpose of optimization is very important to set an initial capacity for the stringbuilder according to the size of the input array (ca 5 * 307K bytes).
@Frisbee: How so? File streams are buffered by default. How would generating all the data then writing it be more efficient than writing the data as it's generated.
Yes, if I do it this way: File.WriteAllText("string2csv.csv", string.Join(";", Values)); it is super fast :) but only 1 long row in excel.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.