-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Convert "Mode" classes to abstract enums. #48
base: master
Are you sure you want to change the base?
Conversation
These classes are basically enums already, just without the benefits.
Just a minor note: Haxe enums are on average 10-40% slower than static inline vars, because they're runtime Objects as opposed to compile time constants. Typically this doesn't matter unless the enum is being used repeatedly in performance critical operations, but there are definitely times that it's more beneficial to use static inlines over enums. The benefits of using an enum do not come without additional overhead in almost all use cases. |
But abstract enums are fine, right? |
They're still slower, I just wanted to point that out. But in this case, the change probably outweighs the cost. |
On Try Haxe, it literally just inlines the variables. How is it slower? |
Its a little bit more complicated than that. Even though it attempts to inline them whenever possible, the compiler generates less optimized code in many cases when using an enum abstract. I think it has something to do with the analyzer. If you compare some more complicated code, you will see that it optimizes the static inline var usage more often, even though they are virtually the same, theoretically. |
For example, here is the generated code(with the analyzer on) of two identical functions, the only difference being one uses an abstract enum value and the other uses a static inline var. The compiler allows unnecessary code(and memory allocations) to run in the former function. And Javascript gets the better of it because it is not strictly typed like C++, where I notice it is often worse. This is a really bad real world example(https://try.haxe.org/#636458B1), but I was using it to test different targets locally with and without the analyzer. In try.haxe, with the analyzer optimization, the abstract enum test always finishes slower by a decent margin, despite the code being basically identical. But once again, I'm not saying we shouldn't do it, only that it seemed like the perfect opportunity to maybe mention the ramifications. Its an issue I've run into in the past when writing my server framework, where every millisecond of cpu time reduction is literally tons of money saved at scale. I just never really talked about it before. |
Interesting. Thanks for the sample! I spotted two code structures that caused a discrepancy. First, declaring a local variable that later gets reassigned. (Which is also known to break constructor inlining, and I doubt that's a coincidence.) Second, using a switch statement, on some targets. Guess the analyzer still has a little ways to go. I don't recall Away3D doing either of those things, and even if it did, this isn't performance-critical code.
The only C++-specific difference I noticed was the switch statement thing. It kept track of types just fine.
Yeah, this was a good time for it. And now I know to keep an eye out for it in performance-critical sections. |
I mean, the analyzer and code generation proficiency in general, not necessarily the example. There are some practices that generate very obtuse C++ that runs slower than its JS counterpart generation, although its not easy to predict or determine what pattern is causing it. |
These classes are basically enums already, just without the benefits. This change should have zero impact on performance or existing code, it'll just make new code a bit simpler.