News for hackers. Stuff that matters.
Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by StefanKarpinski on Sunday October 11, 2020 @03:59PM (#24748601)
Interestingly, CSV.jl can do all of those. This seems like a classic case of lack of composability in Python: you need a different CSV parser for each and every application even though the core logic of parsing the CSV format is the same. This is because anything fast has to be implemented in very concrete, specialized C code. In Julia, you can write something generic and let the compiler specialize it for you, so you get many different ways of applying the same thing for free.
Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by drej on Sunday October 11, 2020 @04:04PM (#24748636)
Lack of composability? What? Of course you can use one parser for everything, what’s stopping you from doing that. Separating IO from business logic and composing the two is a pretty standard practice. Not sure I follow the argument here.
Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by coliveira on Sunday October 11, 2020 @05:16PM (#24749179)
The argument is simple: Python is by design made so that if you want things to go fast then you need to implement it in C. This creates a constant need to use specialized libraries (such as pandas), where in other languages they can simply do a better job in optimizing the standard library.
Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by mlthoughts2018 on Sunday October 11, 2020 @07:53PM (#24750149)
This is untrue, you can compartmentalize your C implementations using tools like Cython.

The fact that you write these as isolated special implementations is a good thing and not a deficiency of generics.

This way it can be gradual. You only target certain functions or modules for optimized C implementation, you don’t waste static typing overhead or compliance to a generic interface on the 99% of the code that will have no material gain from any optimization.

It’s similar with gradual typing in Python as well. Annotate what you need, omit annotations for what you don’t. Implement an extension module or multiple dispatch for what you need, use plain Python for everything else.

Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by mlthoughts2018 on Sunday October 11, 2020 @07:01PM (#24749857)
> “ In Julia, you can write something generic and let the compiler specialize it for you, so you get many different ways of applying the same thing for free.”

Python also lets you easily achieve this in many ways - notably fused typing in Cython.

Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by dagw on Monday October 12, 2020 @02:37AM (#24751967)
Just adding types doesn't give you that much extra performance in cython (2-3x at most in most cases in my experience) if you want 10x+ speed up you generally have to rewrite your code in a more 'cythonic' way.
Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by mlthoughts2018 on Monday October 12, 2020 @06:18PM (#24760105)
I’ve not had the same experience. Simply adding types and omitting CPython types (which results in simpler “basic C” loops and so on) gets 100x speed ups in most situations, and Cython has an annotation mode that highlights CPython bottlenecks to make this very easy and interactive to spot.

With numba it can be even more dramatic. Zero code changes, solely type annotation in the decorator, and you can often get 1000x speedup over pure Python, because numba can optimize away many of the extra CPython data model features that tight loop code may occasionally not need to use.

Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by dagw on Tuesday October 13, 2020 @04:02AM (#24763328)
Do you have any code you can share showing this speed up? Because I have written a lot of Cython over past 5 years, and unless my python code is monumentally stupid (and in that case I can get an order of magnitude or two speedup by just writing sane python), I have never seen anything close to 100x speedup in real world code. Even getting a 5x speed up over a baseline python/numpy implementation requires a fair amount of refactoring to make the code more cython friendly.

Same with Numba, despite its promises, I've never seen anything close to 100x speedups in the real world, and I've even seen a fair few cases where numba resulted in slower code compared to 'pure' python/numpy (although admittedly that was 2-3 years ago)

Sure I could probably design some pathological code where you might see 100x speed up by just adding type annotations, but that would probably require starting with some really inefficient python code.

Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by mlthoughts2018 on Wednesday October 14, 2020 @10:09PM (#24784060)
I do have code I can show, but I do not want to reveal my GitHub username attached to my Hacker News account.

Thankfully you don’t have to rely on me - tons of name brand Python scientific tools use Cython for speedups.

Pandas, for example, uses Cython heavily. Here is an example tutorial that may help you,

https://pandas.pydata.org/pandas-docs/stable/user_guide/enha...

Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by mlthoughts2018 on Sunday October 11, 2020 @04:10PM (#24748685)
> “ Interestingly, CSV.jl can do all of those.“

That sounds like a poorly designed library to me. Instead of doing one thing well, it forces users to consume something meant as a jack of all trades, which may not meet their use case.

I wish such a thing wasn’t forced in a standard package - rather split into different ones. Then I can easily compose them according to my needs, instead of having the stdlib force feed me some set of tradeoffs I might not want.

I’m sure these extra third party libraries exist or will exist in Julia just as they do in Python and users will have lots of good options - but what a shame for people to take a needlessly myopic view that core libraries need to be obsessed either with performance or with breadth of use case coverage coupled into one library, which seems to purely be for macho bragging rights or something?

Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by StefanKarpinski on Sunday October 11, 2020 @07:36PM (#24750052)
That you believe this violates the principle of "do one thing and do it well" indicates a certain "abstraction blindness". Do you really believe that "parse CSV to a data frame" and "parse CSV to a parquet file" and "parse CSV and apply a query to it in-place" are completely separate, unrelated things? It seems clear to me in any case that with the right abstraction, those are the same thing composed with different choices of what to do with the parsed data.

At a higher level, this seems like a classic Julia versus Python dynamic. In the Python ecosystem there are a dozen different versions of each thing that make different trade-offs and specialize in different ways. When you're picking one, you have to spend a week evaluating all the possible CSV parsers (for example).

In the Julia ecosystem, the ideal it to have one really high-quality, fast, flexible implementation that everyone collaborates on to make it great for all kinds of use cases. And the language design and the compiler make this possible, since you can write pretty abstract code and compose it with various types and get a really fast implementation. The annoying and tricky logic of parsing the CSV format only needs to be done once, and reused for all different situations.

This isn't done for "macho bragging rights" but because it is a waste of time and effort to implement a dozen half-baked versions of the same thing. When there are a dozen separate implementations of something like this, they also end up disagreeing on their behavior, which causes no end of headaches.

Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by drej on Monday October 12, 2020 @04:14AM (#24752414)
> In the Python ecosystem there are a dozen different versions of each thing that make different trade-offs and specialize in different ways. When you're picking one, you have to spend a week evaluating all the possible CSV parsers (for example).

It saddens me to read this weird statement. It saddens me as I was a rather early adopter in Julia (v0.3.2, if I remember correctly) and really believed its mission. I don't quite understand why various ecosystems cannot peacefully coexist without these untrue and completely avoidable statements.

Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by mlthoughts2018 on Sunday October 11, 2020 @07:58PM (#24750172)
> “ Do you really believe that "parse CSV to a data frame" and "parse CSV to a parquet file" and "parse CSV and apply a query to it in-place" are completely separate, unrelated things?“

Yes, absolutely. Very high level design goals are completely different between those use cases and you would be forced to make mutually exclusive trade offs to solve any one of those problems - which will directly lead to concessions in terms of the other use cases. No one generic csv parser can be optimal to all three.

Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by StefanKarpinski on Sunday October 11, 2020 @08:22PM (#24750315)
CSV.jl seems to be proof that you're wrong about that. More concretely, the only difference between parsing to a data frame, parsing to a parquet file, and executing a query over data is a) where you put the data in memory and b) optionally calling some code to operate on the data as you go. It's hard to see how those applications require radically different designs.
Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by mlthoughts2018 on Monday October 12, 2020 @06:13PM (#24760050)
This is not accurate. CSV.jl optimizes for speed but does not optimize for data transfer to other systems like Spark (which, by necessity, causes worse performance in order to add features around type marshaling).

Design for general case speed is directly at odds with designing either for executing SQL over top of the file (in which case the trade offs are about indexing the data for record-wise or column-wise operations) or type marshaling for an extremely narrow use case like reading into Spark.

For example, parsing for speed vs parsing for Spark interop are very likely to handle datetime parsing or null parsing significantly differently.

Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by cbkeller on Sunday October 11, 2020 @04:26PM (#24748813)
Well, the promise of overhead-free multiple dispatch is that you don't have to choose between a general solution with poor performance and a specific solution with good performance. You can have all the specific solutions you need in one place and automatically dispatch to the right one without any extra effort.

I know it sounds too good to be true, but my limited experience so far is that it really is true, with surprisingly few pitfalls (mostly, you have to think about type instability, which will be new to most, but is really not that hard to avoid).

Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by mlthoughts2018 on Sunday October 11, 2020 @06:58PM (#24749843)
Multiple dispatch based on static typing only solves a very narrow set of optimization problems - most complex trade offs that would lead to the need for eg multiple different third party csv readers are not addressable at all by multiple dispatch.

I’d also point out that with fused typing in Cython, it’s also trivially easy to get overhead-free multiple dispatch in Python too, and unlike Julia, this had the benefit that it can be a gradual trade off, where you only bother writing the Cython module with autogenerated multiple dispatch implementations based on different types for the ~1% of use cases where it has any impact on the application, and you get the benefit of super easy to develop, flexible Python for everything else, with none of the code liability that comes from describing multiple dispatch generics in the 99% of the code that does not benefit from it.

Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by dklend122 on Sunday October 11, 2020 @11:13PM (#24751089)
You are very misinformed here.

Julia doesn't have static typing and there are a very large set of problems that are trivially solved with it's type system.

See the tables.jl ecosystem for example

Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by mlthoughts2018 on Monday October 12, 2020 @06:25PM (#24760173)
I think you are misinformed. Runtime dispatch on multiple argument types is still using static typing under the hood (Julia is using this, just as Cython is).

The fact that input types are dynamic and resolved at runtime (which works identically in both Julia and Python using a Cython extension module) does not mean the multiple dispatch “is dynamic” (it’s still based on a registry of types that determine which overloaded implementation to select).

The only trade-off is whether you want to be able to extend this registry of static types mapping to implementations on the fly (similar to type classes in Haskell) which Julia supports natively and Python supports via tools like numba, or you need to ahead-of-time compile it (Cython).

This is a trade-off though, between AOT resolver speed vs JIT flexibility. It’s not definitely better one way or the other, and Cython gives you a level of control over explicit language features to enable or disable (eg Exception disabling) that is much better for some use cases.

Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by dklend122 on Tuesday October 13, 2020 @06:03AM (#24763979)
No. You're confusing static dispatch with static typing.

Julia can do both static and dynamic dispatch. The latter works with function barriers works to maintain codebases that are impossible to achieve with just one or the other.

There's no resolving trade-off because when Julia knows types and call time (or a union of them ) it can inline function calls.

Anyway, neither numba nor cython has the combin of features that allows for one to define a fast custom abstract array and have another package seamlessly define a subtype that works fast and with other data structures, overloading only the necessary functions. Then a third package can come and build on top using traits from the first and some weird solver.

Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by mlthoughts2018 on Wednesday October 14, 2020 @10:42PM (#24784308)
No, you are still misunderstanding static type dispatch within a dynamic language. The registry of overloaded specializations works based on static type information. That is not a requirement to have statically typed values (neither in Python nor Julia) but it is still statically typed.
Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by tikej on Sunday October 11, 2020 @07:53PM (#24750146)
> Multiple dispatch based on static typing only solves a very narrow set of optimization problems - most complex trade offs that would lead to the need for eg multiple different third party csv readers are not addressable at all by multiple dispatch.

How about multiple dispatch with dynamic (runtime) typing?

Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by imtringued on Sunday October 11, 2020 @06:32PM (#24749687)
I think parents' point is that a fast CSV parser can be written once and then used to implement many different features. Meanwhile in python every library has to reimplement its own CSV parser because switching from C to python and then back to C would ruin performance. To avoid this context switch the csv parser has to be written again and again.
Re:CSV Reader Benchmarks: Julia Reads CSVs 10-20x Faster tha... by mlthoughts2018 on Sunday October 11, 2020 @07:09PM (#24749902)
This is not true at all. Most libraries do not reimplement csv parsing - I’m saying only a select few libraries do this because they have very different design goals. For example optimizing for maximum rows per second parsed is a totally different design goal from optimizing to read into Spark DataFrame types to connect to Spark. Prioritizing one of these might come at the cost of the other, which is totally fine and having more than one library to choose from is a good thing.

> “ switching from C to python and then back to C would ruin performance.”

This is explicitly wrong in regards to Python. Optimizing Python often involves writing an implementation directly in C (or better, Cython) and autogenerating bindings that marshal between CPython native C types and the types of your extension module. This is extremely fast - as fast as calling native C code, there is no performance penalty for this.