Does it inline?
bolinlang.com
bolinlang.com
Once everything where it should be think about how to process it faster (and you can do ao by swapping out the contents of functional blocks).
If your thing is too big/ slow/ ugly/ stupid, you need to be able to quantify that, so that you can tell whether you really improved it.
If you aren't measuring, any "optimisation" is just wanking, whether you're wanking before the product works or after. If it's many orders of magnitude different the "measurement" may be pretty casual. I had a script which used to take two weeks, now it runs overnight, I can't give you exact timings, however "overnight" versus "two weeks" is a measurement. But often improvements are smaller, which means your measurements need to be more careful.
Measuring also helps focus on actual goals. I'm pretty sure that script could be improved to take under an hour. But, I'm also certain nobody cares whether it takes one hour or ten, so, not a priority. Whereas when it took weeks that was causing problems.
That said, inlining is precisely an area where I find profiling to be difficult. It's difficult to see where in a function time is spent if a lot of function-calls in that function are inlined. However, I'm not certain that the every part of my code is equally slower/faster depending on what optimizations I turn on/off in the compiler. Thus, reducing optimizations might give me the wrong impression about which functions take up the most runtime.
Deleting a call that always returns 0 is a different optimization called “interprocedural constant propagation”.
I was hoping more comments would discuss this
Probably a wise choice, as people are usually taught to hit the Allocator like a Piñata full of candy. =)
What you'd need to do for assessing intuition is finding some actual common/realistic cases, then seeing how accurately people perform on those - things that are useful, and which people might actually claim to have intuition about! Moreover, also note that someone with "good intuition" for inlining wouldn't necessarily know (or need to care) what happens at every call site - sometimes it doesn't really matter what specific level the inlining stops at, as long as most of the call chain is inlined, and that's what intuition often gets you.
I think this is actually great support for their thesis. If you came across actual code that looked like that (and god knows it probably exists if it's legal), who fucking knows what the compiler would do?
My question is: why is it even legal to mark functions with both of these, in addition to the `inline` keyword? My guess is the C++ spec says something along the lines of "you can mark functions with as many attributes as you want .. something .. something .." ie compiler vendors get no choice but to (at best) emit a warning.
It most certainly exists, even if it's actually illegal. I mean, come on, how many are there C codebases with more than 10k lines that have absolutely zero UB? I've seen several C programmers who, when "wrestling the compiler" to emit some certain kind of pattern in the resulting assembly, would do bloody anything without much regard whether what they wrote was legal, or implementation-specific, or UB. "It compiles to what I want with the compiler we use today, that's all that matters. We'll probably change it in the future if it breaks".
In C++ marking an inline function no_inline is actually meaningful: the inline specifier has little to do with actually performing the inlining optimization and for the most part it means that the ODR rules are weakened (in practice enabling vague linkage). The no_inline attribute instead prevents the optimization from occurring. So an inline no_inline function is a function with vague linkage that should not be inlined.
As it allows the function to be defined in an header file and usually a function body need to be available in a translation unit, functions that should be inlined are often marked as inline (which also acts as a weak hint to the optimizer), but it is neither necessary nor sufficient. And the naming is of course for the most part historical.
Outside of the first two rounds most of these were inspired by real code but simplified for reading. I think it'd be less entertaining if it was more serious and more had realistic code. A lot more people would tune out. If it was any longer I think it would have made more sense to explain why something was optimized or not. I don't work on clang or gcc so I may not be a good person to write that kind of article
> someone with "good intuition" for inlining wouldn't necessarily know (or need to care) what happens at every call site
Round 5 (the virtual function/dynamic cast round) was inspired by a person who claimed to have 20 years of experience. He suggested a way I could implement a feature in my compiler. I eventually wrote a test case to see if compilers would 'devirtualize' function calls as he claimed. They didn't. From memory he works on making servers preform so he wasn't a stranger to performance. I think "good intuition" is more about knowing what won't inline and having some tactics you can use in the first 5 minutes after looking at a flamegraph
From what I've seen, dynamic_cast is implemented as an opaque external function call (and quite a complicated one), so the compiler would need to explicitly make assumptions about its behavior before it can optimize it away. (Which it certainly could, but that's extra work for the compiler writer that would need to be worth the payoff, which in this case I imagine is probably debatable.) Virtual functions, on the other hand, don't involve an opaque call for mere target resolution, and their vtables have definitions available at compile time, so they're much more tame. So expecting devirtualization to come with dynamic_cast getting optimized away seems a bit of a non-sequitur IMO.
Most of the time using contexpr and defining inlineable functions in headers will get you the most optimal result. In the most of the remaining part the compiler is again right to not inline things because it probably knows more about the instruction caches etc than you. The remaining tiny part is basically PhD or very expert level experience which makes it your job to know more than the compiler because it is your job to write the compiler or discover its shortcomings.
int f(int x) {return x + 1;}
int main() {
int y = f(3); // this will change
return 0;
}
inline means to substitute the body of the function into the call site: int y = 3 + 1;
comptime means to substitute the results of the function call into the call site: int y = 4;
An inline function only requires that the compiler decide the function body is "small enough" and not recursive. The compiler simply rewrites the AST before codegen.But comptime evaluation means that the compiler has actually run the function ahead of time. (This might be done via a builtin virtual machine, for example.) The requirements are that the function is "pure" (no side effects) and that the inputs can also be resolved ahead of time.
A recursive function could be comptime but not inline, whereas a function with IO could be inline but not comptime. The above incrementing function just happens to be both inline and comptime.
I gather that zig "comptime" is somewhat like C++11 "constexpr".
https://www.hackingnote.com/en/cpp/const-vs-constexpr/index....
> Not to be confused with automatic memory which completely works, memory safety isn't fully implemented. We use invalidation to say all references that came from that object are no longer valid. This is checked at compile time. Not everything has been implemented so there are holes and we haven't chosen alias rules which might be a simple not allowed.
They've certainly made some interesting decisions.
The next update should be large