4 ms·
casey muratori would like to have a talk with you about the following :)) // Approximately what the JIT generates if (animal?.GetType() == typeof(Dog))
by momocowcow 9d ago
casey muratori would like to have a talk with you about the following :))
// Approximately what the JIT generates
if (animal?.GetType() == typeof(Dog))
{
((Dog)animal).Speak(); // devirtualized, inlinable
}
else
{
animal.Speak(); // original virtual call, hopefully rare
}
- kg 9d agoYou can always just not use OOP. C#'s tooling for functional programming and C-style programming is really good, thanks to stuff like statics on interfaces or spans.
- program_whiz 9d agoactually this is likely just as performant as the "Ugly but fast" code from the famous talk. After all, this is just branching on GetType() == typeof(Dog) which is presumably boiling down to an integer comparison. This roughly the same as the following C code: void speak_generic(void* animal, int type_id) { if (type_id == DOG) { dog_speak((Dog*)animal); } else { dispatch_speak_vtable(animal); } } Advantage 1: You don't have to maintain this logic (its automatic), so you won't get weird cases if you forget to update all your switches everywhere, and/or you get weird fallthrough logic and footgun yourself in C. Advantage 2: You still get the flexibility of the vtable if you need it (for the case the type is chosen at runtime at not known). But for 90% of cases, its just as fast as the ugly C code. Disadvantage 1: Losing a smug sense of superiority because you eschew abstractions and prefer writing verbose error-prone switch statements over clean easy to understand code. Disadvantage 2: Writing performant code can no longer be gate kept behind archaic practices, now everyone can just use `var animal = new Dog()` and be done with it.