Live data from Hacker News

World's Smallest CSV Parser (C#)

github.com

31–40 of 72 posts

Re: World's Smallest CSV Parser (C#)

#31
post #15

Very nice. The submission's main file (SmallestCSVParser.cs) is 3851 characters (of which 657 are commentary). Mine, in C, is only 2807 characters (of which 198 are commentary): https://github.com/semitrivial/csv_parser/blob/master/csv.c Ahh, but the submission's main file is for parsing an entire .csv, whereas mine is only for parsing a single "line" (possibly including quote-escaped newlines). So the submission win…

Do you need more than 1k of additional source to wrap the line parsing in a loop? I doubt it.

Re: World's Smallest CSV Parser (C#)

#33
post #27

Earlier quoted context omitted.

If you (a consuming dev) want the world's smallest (in your code) - use the .net built in parser[0]. Bonus, it's RFC4180 compliant. If you (competing/learning) want to write the world's smallest (code golf style)... this isn't it, and has some weird superfluous lines (if that's your measure - per the original question). If you (learning) want to write an efficient parser.. this isn't it. You don't need a StringBuilde…

This is not a correct link (it refers to VB.NET). There are better parsers out there (Sep). I'm not sure what is your point but it certainly misses the idea behind this HN submission and makes me sad as it would be nice to see words of encouragement in .NET submissions here instead.

It's an assembly with "Microsoft.VisualBasic" in the name, but it shipped as part of every version of .NET to date, and is perfectly usable from C#. In fact, I would be very surprised if there aren't vastly more uses of this API from C#, since it's a very old trick of the trade.

What GP is saying is that, given that it is already included in the standard class library, it's always the cheapest option wrt size of your shipping app. So it should arguably be the default choice for any .NET dev unless they either need better performance or some more exotic requirements wrt input format.

Re: World's Smallest CSV Parser (C#)

#34

Earlier quoted context omitted.

Fun! Convert to js: csv.split('\n").join('".split(\',\'));a.push("'); So that each line becomes: a.push("foo,bar,baz".split(',')); And then we have an array of arrays.

Of course the “hard part” of CSV parsing is dealing with escapes, which break simple splits. But now I’m wondering if a good approach might be to split on the escape character and then reassemble / parse from there, safe in the knowledge that every character has exactly one interpretation.

"Normal" CSV doesn't have escape characters. Quotes in quoted strings are escaped by doubling then, and everything else (including newlines) is interpreted as is inside quoted strings.

Re: World's Smallest CSV Parser (C#)

#35

Earlier quoted context omitted.

> Why not use ... a plain Exception. It is forbidden. https://learn.microsoft.com/en-us/dotnet/standard/exceptions... > Exception ... None (use a derived class of this exception). https://learn.microsoft.com/en-us/dotnet/standard/design-gui... > DO NOT throw System.Exception or System.SystemException.

I'm not seeing where it says not to throw InvalidOperationException.

If you want to recover from CSV errors you should ideally throw InvalidCSVException.

Re: World's Smallest CSV Parser (C#)

#36
That’s still multiple lines of code.

Here’s one in c++ that uses only a single line of code (excluding function headers)

// How do I format this as code?

vector split( const string& s) { return accumulate(s.begin(), s.end(), vector(1), [=](auto acc, char c) { if (c == ‘,’){ acc.push_back(string()); } else { acc.back( ) += c; } return acc; } ); }

Re: World's Smallest CSV Parser (C#)

#37

Earlier quoted context omitted.

> Why not use ... a plain Exception. It is forbidden. https://learn.microsoft.com/en-us/dotnet/standard/exceptions... > Exception ... None (use a derived class of this exception). https://learn.microsoft.com/en-us/dotnet/standard/design-gui... > DO NOT throw System.Exception or System.SystemException.

I'm not seeing where it says not to throw InvalidOperationException.

InvalidOperationException means "the object is in an inappropriate state". That does not describe a parse error.

C# conventions for exceptions are admittedly a bit confusing. There are a handful of very specific scenarios where you're supposed to use a built-in exception (most commonly ArgumentException). For everything else, you want to define your own type.

Re: World's Smallest CSV Parser (C#)

#38

Earlier quoted context omitted.

Fun! Convert to js: csv.split('\n").join('".split(\',\'));a.push("'); So that each line becomes: a.push("foo,bar,baz".split(',')); And then we have an array of arrays.

Of course the “hard part” of CSV parsing is dealing with escapes, which break simple splits. But now I’m wondering if a good approach might be to split on the escape character and then reassemble / parse from there, safe in the knowledge that every character has exactly one interpretation.

I think of what you say as really just the first step on the path to the parsing state machine in the c2tsv.nim (or /c2dsv.c in the same folder) thing I mentioned above which have comments in their source code.

I think it helps to think of the problem more like "How do I translate a complex syntax buffered input stream which 'most' of the time just translates ',' to '\t' into a buffered output stream that is "almost" as fast as a Unix `tr , \\t`?" If there were no escaping/quoting the output buffer could literally be the same memory as the input, just with the delimiter bytes changed.

The next step is realizing that you can still just do this byte translation if you "flush" the IO buffer opportunistically at syntactically relevant times. That gets you the "almost" performance. (Scare quotes on "almost" since you might do a few more IO-system calls with certain kinds of dense syntax, but unlike your "reassemble" there won't be any allocations. Various trade-offs, but a nifty design.)

There are other nice aspects to the "partitioned program design" mentioned a sibling-ish comment, but, all together, I think it is a pretty tidy solution.

Re: World's Smallest CSV Parser (C#)

#39
post #33

Earlier quoted context omitted.

This is not a correct link (it refers to VB.NET). There are better parsers out there (Sep). I'm not sure what is your point but it certainly misses the idea behind this HN submission and makes me sad as it would be nice to see words of encouragement in .NET submissions here instead.

It's an assembly with "Microsoft.VisualBasic" in the name, but it shipped as part of every version of .NET to date, and is perfectly usable from C#. In fact, I would be very surprised if there aren't vastly more uses of this API from C#, since it's a very old trick of the trade. What GP is saying is that, given that it is already included in the standard class library, it's always the cheapest option wrt size of your…

What is it with .NET or C# submissions (but I suppose other languages are not immune either) that attracts this type of replies, which miss the point behind a particular piece of code, trivial or not?

Yes, there are existing implementations, many of which are incomparably better, one of which ships with default project SDK (even if it is effectively obsolete[0]). But surely offering a competitive implementation that intends to replace existing solutions wasn't the purpose of this?

Either way, I'm not the author of the code and have already spent enough (free) time in the last 8 months working on a string library which has performant parsing as one of the project goals[1].

[0] https://github.com/dotnet/runtime/tree/main/src/libraries/Mi...

[1] https://github.com/U8String/U8String

Post reply on HN