I know I'm 9 months late, but I really enjoyed this video. You did a really great job of clearly explaining a complex topic. I wanted to mention that it is not necessarily true that the compiler generates more code in the templated case. Just because the compiler could generate implementation code for all the different Logger types does not mean that it is under obligation to do so. At the time of compilation, it is set in stone which implementation(s) will be required, so the compiler is free to generate only the code which is required at each generic reference. In a typical logging scenario, this would be one kind of logging for the entire binary, across all function calls which uses such a reference. And, indeed, that is what your analysis of the object code reveals at the end.
The only performance problem with rust is when the borrow-checker rejects perfectly sound code that would be more performant than what it takes to satisfy the borrow checker. Otherwise, it has a zero-cost abstraction. But the borrow-checker is one of my favorite features.
From the presentation I didn't understand if the runtime polymorphic version of the function can cohesist together with the compile-time polymorphic version of the same function...
In my experience generics used in this style don't scale well. If your method internally uses X which then internally uses Y, Z, W, then the template function ends up having to expose X, Y, Z, W. It grows and grows with each level of wrapping. You can use generics in this style in C# or Java or any other more traditional language. And in C# at least with structs it essentially also incurs zero cost. It would be cool to invent a zero-abstraction pattern that actually scales.
The generics approach is considered much more idiomatic, and should be preferred in general. Where you wouldn't be able to use generics, would be in scenarios where you need dynamic dispatch (i.e. when using trait inheritance).
Great talk, thanks a lot! The part about the difference between the compilation of generics vs trait objects was an eye opener for me :)
We need more talks like this. This helps the way we code by understanding the performance implications.
Wow! Great talk! Dove into the compiler optimizations while keeping the explanation simple and direct.
I know I'm 9 months late, but I really enjoyed this video. You did a really great job of clearly explaining a complex topic.
I wanted to mention that it is not necessarily true that the compiler generates more code in the templated case. Just because the compiler could generate implementation code for all the different Logger types does not mean that it is under obligation to do so. At the time of compilation, it is set in stone which implementation(s) will be required, so the compiler is free to generate only the code which is required at each generic reference. In a typical logging scenario, this would be one kind of logging for the entire binary, across all function calls which uses such a reference. And, indeed, that is what your analysis of the object code reveals at the end.
New to programming here. Worked about halfway through nand2tetris and this talk was fuel on the fire! Accessible and interesting.
Thank you!
damn - short, sweet, and to-the-point.
fantastic!
Clear presentation, straight and to the point!!
The last part was really interesting. I wonder if it's the same in C++.
Amazing talk, clear my doubts about traits! Thanks a lot!
The only performance problem with rust is when the borrow-checker rejects perfectly sound code that would be more performant than what it takes to satisfy the borrow checker. Otherwise, it has a zero-cost abstraction. But the borrow-checker is one of my favorite features.
thank you
Great presentation Tim!
Really awesome talk!
From the presentation I didn't understand if the runtime polymorphic version of the function can cohesist together with the compile-time polymorphic version of the same function...
Very insightful, thanks!
In my experience generics used in this style don't scale well. If your method internally uses X which then internally uses Y, Z, W, then the template function ends up having to expose X, Y, Z, W. It grows and grows with each level of wrapping. You can use generics in this style in C# or Java or any other more traditional language. And in C# at least with structs it essentially also incurs zero cost. It would be cool to invent a zero-abstraction pattern that actually scales.
How to see that machine generated code?
Probably objdump with -s (I believe... going by memory here).
21:05 Generics vs Traits
Or, make the compiler work as much as possible. Compile once, execute a billion times. Good choice.
I wasn't aware of the possibility of using generics in place of trait objects. Are there places where you can't do that?
The generics approach is considered much more idiomatic, and should be preferred in general. Where you wouldn't be able to use generics, would be in scenarios where you need dynamic dispatch (i.e. when using trait inheritance).