6 ms·
The point around Julia's performance is often in the context of mathematical computing. The two languages are designed for very different use cases. Julia is d
by ViralBShah 9y ago
The point around Julia's performance is often in the context of mathematical computing. The two languages are designed for very different use cases.
Julia is designed to make it extremely easy to write high performance mathematical programs with ease. Rust is designed to make it easy to do systems programming. Both are high performance for the things they are designed to do. Just like I wouldn't do systems programming in Julia (although I am certain KenoFischer would), I wouldn't want to do mathematical computing in Rust.
- vvanders 9y agoSure but mathematical problems don't exist in isolation. I used to do a ton of 3D graphics work with matrices, vectors, etc. We definitely couldn't use something that didn't have the right support for data layout and good runtime semantics. C/Rust/C++ fit that very well so I wanted to understand how similar claims were made for a GC'd language. C# for instance can work with value types and was wondering is Julia has similar constructs.
- ballenarosada 9y agoValue types are also addressed in the article
- vvanders 9y agoFrom what I can find[1] it looks like while Julia has compact values it doesn't have what I'd traditionally call value types. Specifically value types that live on the stack unless they are a member of a reference type(which is what C# does). Looking at the performance docs[2] this is pretty clear in that array types(which looks like how Julia does Matrices) get allocated on the heap. You can clearly see the performance impact in the docs(1.95s vs 0.08s) that this type of behavior has. While you can preallocate(which the docs suggest and is the only path for GC'd languages) it's not an ideal solution. If your type is smaller than a single cache line, like in the example above, you've just flushed a whole cache line just to bring in that one pre-allocated value. You also run into the issue if you don't know exactly how many values you need upfront which leads to pooling. In that scenario your pool may be large enough that you're bouncing between cache lines on different pooled objects. This is the type of thing that you really need control over if you want performance "as good as C". Anything less will be a compromise. There's also the whole class of zero-cost abstractions that can get from C++/Rust which leverage all the above to great effect. That lets you get things like nom[3] which gives you high level semantics + productivity while maintaining parity with C. None of this is academic, these are all optimizations I've used on shipping products that went out to millions of users. In each case we had fixed hardware with a limited execution budget and the 5-20x improvements we made were critical to us shipping a product that people wanted to use. [1] https://discourse.julialang.org/t/how-to-know-if-object-memory-resides-on-stack-or-heap/4927 https://discourse.julialang.org/t/how-to-know-if-object-memo... [2] https://docs.julialang.org/en/release-0.4/manual/performance-tips/#pre-allocating-outputs https://docs.julialang.org/en/release-0.4/manual/performance... [3] https://github.com/Geal/nom_benchmarks/tree/master/http https://github.com/Geal/nom_benchmarks/tree/master/http / https://github.com/Geal/nom https://github.com/Geal/nom
- KenoFischer 9y agoFor values with compiler-visible scoped lifetime, the compiler will automatically promote them to stack variables. There is currently no way to enforce this happening, but it would be perfectly possible to add such an annotation. Regarding preallocation, you tend to want to avoid dynamic memory allocation in high performance applications anyway, so whether you do that in C++ or in Julia, doesn't really make too much of a difference. It is true this is a little harder to control in GC'ed languages than in languages where you have to do memory management manually, but the effect is about the same. Julia provides tools to figure out where you're using dynamic memory allocation and those tools will certainly improve in the future. One thing I think is under appreciated from the performance perspective though is how easily julia lets you express data layout transformation to take better advantage of the cache hierarchy. I touched on this a bit in my JuliaCon presentation [1]. [1] https://youtu.be/uecdcADM3hY?t=32m19s https://youtu.be/uecdcADM3hY?t=32m19s
- vvanders 9y ago> Regarding preallocation, you tend to want to avoid dynamic memory allocation in high performance applications anyway, so whether you do that in C++ or in Julia, doesn't really make too much of a difference. Yes! Which is why it shouldn't take me digging through 3 different documents and still getting it partly wrong! C/C++/Rust make this easy by annotating the type modifiers(&/*/Box/etc) with how the object lives in my runtime system. Rust even gets bonus points for giving me aliasing information as well(&mut vs &).
- ChrisRackauckas 9y agoYou just do @. and you're done?
- bjourne 9y ago> For values with compiler-visible scoped lifetime, the compiler will automatically promote them to stack variables. There is currently no way to enforce this happening, but it would be perfectly possible to add such an annotation. Other languages such as Java have that optimization too. But it is quite limited because it can only be applied to data whose size is known at compile-time. There is also the problem that if some data allocated in a procedure is passed to another procedure, it can't be allocated on the stack because it can escape. A programmer working in a low-level language can be smart and choose the best locations (stack or heap) for each piece of data. A language that does not allow explicit stack access (like C does), can never make as optimal decisions.
- omginternets 9y agoIn the case of research, data-science and -- generally speaking -- "scientific computing", mathematical problems pretty much do exist in isolation. This is the niche that Julia wants to occupy.
- vvanders 9y agoIf that were the case I wouldn't have an adjacent subthread telling me that they are pretty much the same ;). To be clear, I have no beef with Julia, I'm sure it's a fantastic language. I take issue with people thinking they can get the same level of performance without explicitly controlling their memory access patterns/allocations. 98% of developers will never need it in their careers but when you do there is no substitute.
- CyberDildonics 9y agoWhy don't you think you can control those things? Make an array, loop through linearly, just like C. Avoid allocations in inner loops, just like C.
- xfer 9y agoI agree, a lot of the performance problems have to with allocation in any language, gc'd or not. I still can't believe people making the same argument against gc'd languages even when highly performant jvm exists.
- CyberDildonics 9y agoI don't see too many reasonable arguments that garbage collection is slower. Taking up more memory, having pauses and requiring the same amount of thought as modern C++ are all arguments I've heard, which is my experience with Julia (sans the pauses since I haven't done something interactive yet).
- xfer 9y ago
- andyferris 9y agoJust thought I'd chime in that there is a StaticArrays.jl package that lets you make arrays which are stack allocated like value types in other languages, and you can make arrays of static arrays that layout exactly like arrays of structs in C/C++, and can be memory mapped from disk and so-on. (Such arrays of static arrays do eventually get GC'd, but that is not necessarily very frequent). They also support the same set of abstractions as other arrays including performant (SIMD) math/linear algebra that in my (biased) opinion is perfect for 3D graphics. (As an aside, we also take this further with abstractions of 3x3 rotation matrices using a variety of internal representations such as quaternions in Rotations.jl, and allow composing coordinate transformations in CoordianteTransformations.jl, etc, etc). Touching on the original authors post about the package ecosystem, I feel it can't be understated enough how easily different packages can compose and be used together in Julia. I like to say there is a product rule here where functionality/productivity grows as the square of the number of packages/features you can use together naturally (regardless of programming language). We can use static arrays, rotations, coordinate transformations, etc in combination with differential equation packages to simulate a system or with an optimization package to optimize a coordinate transformation for SLAM given certain measurements, and so-on, at full run-time speed but comparatively little user effort.
- KenoFischer 9y ago> although I am certain KenoFischer would Sure would.