4 ms·
> and this was without any Julia-specific optimizations other than adding types to the function arguments. I know this wasn't the point of your post, but just
by affinepplan 3y ago
> and this was without any Julia-specific optimizations other than adding types to the function arguments.
I know this wasn't the point of your post, but just noting that adding types to function arguments "usually" shouldn't impact performance at all :)
when it does, that might mean there is some type-instability being papered over (i.e. there is a better fix lurking around the corner)
- tombert 3y agoIn one case adding type information into the function args, for a function with a loop being run like 20 million times, it made a pretty substantial difference; it brought processing down from roughly 2 minutes to roughly 10 seconds. I didn't do a control test to figure out exactly why, but I think it was having some issue with a parsed CSV being read as a matrix. I think explicitly putting that requirement into the function signature allowed for a lot of low-level optimizations to be used that it couldn't use before. I'm not 100% sure though; basically when I was getting some performance bottlenecks I did some preliminary searching and some of the results said "try adding types to your function signatures", and I really couldn't think of a good reason not to add them for most of the variables, and so I did and it worked.
- samatman 3y agoWhat grants speed to Julia code is type assertions, at least in the case where the assertions lead to type stability. The compiler balances speed (of compilation) and accuracy, when inferring types and deciding what methods to specialize. If and when it can't figure that out, adding a type assert give it more ability to assume the assertion is accurate. Concrete types in a function signature also work as assertions, so it's one way to force the compiler's hand this way. In many cases it's better to assert the arguments, rather than the parameters, to keep the method itself generic. The main reason to add types to a method is to allow multiple dispatch to pick that method of the function for values of the specified type.
- ChrisRackauckas 3y ago> Concrete types in a function signature also work as assertions, so it's one way to force the compiler's hand this way. In many cases it's better to assert the arguments, rather than the parameters, to keep the method itself generic. The main reason to add types to a method is to allow multiple dispatch to pick that method of the function for values of the specified type. No they do not, this is not how it works. Functions auto-specialize on the types they see and do a multiple dispatch behind the scenes on these specializations. Type parameters in a function signature thus only define what specializations are allowed. See https://book.sciml.ai/notes/02-Optimizing_Serial_Code/ https://book.sciml.ai/notes/02-Optimizing_Serial_Code/ for details. As such, you don't need to add any types to a function signature to get performance.
- tombert 3y agoThat makes sense; basically giving a hint so that the compiler can figure out what kind of special optimizations are possible. I would assume that it can avoid extra reflection calls as well as a result? The slow function I added the types to didn't really make any sense to be really generic. For nearly all the arguments (of which there was like 20), there was only one type that made any sense for each. I don't think keeping it more generic would have bought me much, and adding types worked as an assertion that made things much faster. But yes, once I started adding types to thing, I did start utilizing multiple dispatch, since I've always been a bit fan of Clojure-style multimethods and this got me something more or less comparable to it.