Update
This commit is contained in:
parent
f7e0fb4b27
commit
556653d6e4
28 changed files with 190 additions and 41 deletions
|
@ -10,12 +10,13 @@ These are mainly for [C](c.md), but may be usable in other languages as well.
|
|||
- **gprof is a utility you can use to profile your code**.
|
||||
- **`<stdint.h>` has fast type nicknames**, types such as `uint_fast32_t` which picks the fastest type of at least given width on given platform.
|
||||
- **Keywords such as `inline`, `static` and `const` can help compiler optimize well**.
|
||||
- **Optimize the bottlenecks!** Optimizing in the wrong place is a complete waste of time. If you're optimizing a part of code that's taking 1% of your program's run time, you will never speed up your program by more than that 1% even if you speed up the specific part by 10000%.
|
||||
- **Optimize the [bottlenecks](bottleneck.md)!** Optimizing in the wrong place is a complete waste of time. If you're optimizing a part of code that's taking 1% of your program's run time, you will never speed up your program by more than that 1% even if you speed up the specific part by 10000%. Bottlenecks are usually inner-most loops of the main program loop, you can identify them with [profiling](profiling.md).
|
||||
- **You can almost always trade space (memory usage) for time (CPU demand) and vice versa** and you can also fine-tune this. You typically gain speed by precomputation (look up tables, more demanding on memory) and memory with compression (more demanding on CPU).
|
||||
- **Learn about [dynamic programming](dynamic_programming.md)**.
|
||||
- **Avoid branches (ifs)**. They break prediction and instruction preloading and are often source of great performance losses. Don't forget that you can compare and use the result of the operation without using any branching (e.g. `x = (y == 5) + 1;`).
|
||||
- **Use iteration instead of [recursion](recursion.md)** if possible (calling a function is pretty expensive).
|
||||
- **Avoid branches (ifs)** if you can (remember [ternary operators](ternary_operator.md), loop conditions etc. are branches as well). They break prediction in CPU pipelines and instruction preloading and are often source of great performance losses. Don't forget that you can many times compare and use the result of operations without using any branching (e.g. `x = (y == 5) + 1;` instead of `x = (y == 5) ? 2 : 1;`).
|
||||
- **Use iteration instead of [recursion](recursion.md)** if possible (calling a function costs something).
|
||||
- **You can use good-enough [approximations](approximation.md) instead of completely accurate calculations**, e.g. taxicab distance instead of Euclidean distance, and gain speed or memory without trading.
|
||||
- **Use quick opt-out conditions**: many times before performing some expensive calculation you can quickly check whether it's even worth performing it and potentially skip it. For example in physics [collision detections](collision_detection.md) you may first quickly check whether the bounding spheres of the bodies collide before running an expensive precise collision detection -- if bounding spheres of objects don't collide, it is not possible for the bodies to collide and so we can skip further collision detection.
|
||||
- **Operations on static data can be accelerated with accelerating structures** ([look-up tables](lut.md) for functions, [indices](indexing.md) for database lookups, spatial grids for collision checking, ...).
|
||||
- **Use powers of 2** whenever possible, this is efficient thanks to computers working in binary. Not only may this help nice utilization and alignment of memory, but mainly multiplication and division can be optimized by the compiler to mere bit shifts which is a tremendous speedup.
|
||||
- **Write [cache-friendly](cache-friendly.md) code** (minimize long jumps in memory).
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue