4 ms·
The standard optimization user case story is absurd. 1. You’re not gonna get any guarantees that the optimization will happen. That makes it High Level. Just w
by keybored 2y ago
The standard optimization user case story is absurd.
1. You’re not gonna get any guarantees that the optimization will happen. That makes it High Level. Just write code. We won’t force you to pollute your code with ugly annotations or pragmas.
2. In turn: check the assembly or whatever the concrete thing that reveals that the optimization you wished for in your head actually went through
There’s some kind of abstraction violation in the above somewhere.
- jiggawatts 2y agoI have the same experience with database query planners. The promise is that you just write your business logic in SQL and the planner takes care of the rest. In practice you spend weeks staring at execution plans.
- dspillett 2y agoA key difference between many compilers and DB query planners, is that a compiler can spend more time over its optimisations because it is run dev-side and the benefits (and none of the time taken) are felt by the users. A query planner needs to be more conservative with its resource use. This is not true of JIT compilers, of course, which have similar constraints to DB query planners. In these cases the goal is to do a good job pretty quickly, rather than an excellent job in a reasonable time.
- jiggawatts 2y ago> A query planner needs to be more conservative with its resource use. The number of possible distinct query plans grows very rapidly as the complexity increases (exponentially or factorially... I can't remember). So even if you have 10x as much time available for optimisation, it makes a surprisingly small difference. One approach I've seen with systems like Microsoft Exchange and its undrelying Jet database is that queries are expressed in a lower-level syntax tree DOM structure. The specific query plan is "baked in" by developers right from the beginning, which provides stable and consistent performance in production. It's also lower latency because the time spent by the optimiser at runtime is zero.
- pjmlp 2y agoHowever most big boys databases also package a JIT compiler into the mix, making it more fun.
- dspillett 2y agoAs the optimal plan will change as data sizes and patterns do, it is almost all JIT with fairly aggressive caching. They keep some stats on each object and plan to help guess when a cached plan should be used or the full planner be engaged again, though this process often needs a little help.
- joncrocks 2y agoQuery planners can (and will) use statistics gathered on the contents of the tables to more effectively execute queries, which can be gathered in the background/batch processes. For large database vendors there is a good amount of complexity put into up-front information gathering so that query execution is fast.
- mamcx 2y agoAn even bigger issue is that regular optimizer see a whole static world (the code). You can know very well the size of most things. For DBs, it would be 'trivial' if we could know the exact (or very very close) size of the tables and indexes. But the db is a mutating environment, that start with 1 row and 1 second later is 1 million, and 1 second later is 1 row again. And then you mutate it from thousands of different connections. Also, the users will mutate the shape, structure, runtime parameters, indexes, kind of indexes, data types, etc.
- glitchc 2y agoAgreed. You put your finger directly on something that's always bugged me about optimistic code optimization strategies. The code I write is supposed to have deterministic behaviour. If the determinism changes, it should be because of a change I made, not a flag in the compiler. The behaviour is completely opaque and uncorrelatable, makes it very hard to figure out if a given change will lead to better or worse performance. "Abstraction violation" is a good way to put it.
- rocqua 2y agoThe excuse for this is that performance is not considered part of the behavior of the program. So it doesn't matter to the question of whether your program is deterministic.
- glitchc 2y agoExcept for the fact that performance optimization frequently does change the behaviour of the program.
- mrob 2y agoIf performance optimization changes anything other than performance it's either a bug in the program or a bug in the compiler.
- naasking 2y agoYes, but program bugs are obviously very, very common. Developers already do a great job of adding bugs to their programs, they don't need compilers compounding that problem in non-deterministic ways.
- rocqua 2y agoThat is only possible if the optimization is wrong (rare), or the program already had undefined behavior (very common, because undefined behavior is very easy to trigger in C).
- randomNumber7 2y agoWhen you already know what you want to have after the optimization, you could just write that code in the beginning.
- aleph_minus_one 2y agoNot all programming languages have this amount of expressiveness. How do you, for example, tell how a database what the intended execution plan is for some complicated SQL query? You can normally only send SQL queries to a database and not execution plans.
- Spivak 2y agoI've always wanted to just write the execution plan directly and bypass the planner for a few hot queries.
- magicalhippo 2y agoUsing bit rotation instructions in C is another case I recall. Since there's no bit rotate operator in C, you're left hoping the compiler recognizes what the shifts and bitwise-ands are trying to do.
- 2y ago
- GuB-42 2y agoIt is a leaky abstraction, all abstractions are. I didn't find it to be much of a problem in practice. Usually, if you don't get the optimization you wished for, it means that there is something you didn't account for. In C++, it may be exception processing, aliasing rules, etc... Had the compiler made the optimization you wished for, it wouldn't have been correct with regard to the specifications of the language, it may even hide a bug. The solution is then to write it in a way that is more explicit, to make the compiler understand that the edge case can never happen, which will then enable the optimization. It is not really an abstraction violation, more like a form of debugging. If you really need to get low level, there is some point where you need to write assembly language, which is obviously not portable, but getting every last bit of performance is simply incompatible with portability.
- keybored 2y ago> It is a leaky abstraction, all abstractions are. It’s not leaky (and that term is kind of meh). It’s just an abstraction! Such optimizations are supposed to be abstracted away (point 1).[1] The problem comes when that is inconvenient; when the client does not want it to be abstracted away. There’s a mismatch there. [1] EDIT: The point here is that the API is too abstracted compared to what the client wants. Of course the API could choose to not abstract certain things. For example the Vec[2] type in Rust has specified, as part of the documentation, how it is implemented (to a large degree). They could call it something like “List” and say that whatever the concrete implementation is, is an implementation detail. But they chose not to. [2] https://doc.rust-lang.org/std/vec/struct.Vec.html#capacity-and-reallocation https://doc.rust-lang.org/std/vec/struct.Vec.html#capacity-a...