Update
This commit is contained in:
parent
b028290107
commit
ca8db11490
11 changed files with 67 additions and 16 deletions
|
@ -2,23 +2,26 @@
|
|||
|
||||
Optimization means making a program more efficient in terms of some metric such as speed or memory usage (but also others such as power consumption, network usage etc.) while preserving its functionality.
|
||||
|
||||
Unlike [refactoring](refactoring.md), oprimization changes the behavior of the program to a more optimal one (but again, it doesn't change its functionality).
|
||||
Unlike [refactoring](refactoring.md), optimization changes the behavior of the program to a more optimal one (but again, it doesn't change its functionality).
|
||||
|
||||
## General Tips'n'Tricks
|
||||
|
||||
These are mainly for [C](c.md), but may be usable in other languages as well.
|
||||
|
||||
- **Tell your compiler to actually optimize** (`-O3`, `-Os` etc.).
|
||||
- **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%.
|
||||
- **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).
|
||||
- **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.
|
||||
- **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 code** (minimize long jumps in memory).
|
||||
- **Compare to [0](zero.md) if possible**. There's usually an instruction that just checks the zero flag which is faster than loading and comparing two arbitrary numbers.
|
||||
- **Write [cache-friendly](cache-friendly.md) code** (minimize long jumps in memory).
|
||||
- **Compare to [0](zero.md) rather than other values**. There's usually an instruction that just checks the zero flag which is faster than loading and comparing two arbitrary numbers.
|
||||
- **Consider moving computation from run time to compile time**. E.g. if you make a resolution of your game constant (as opposed to a variable), the compiler will be able to partially precompute expressions with the display dimensions and so speed up your program (but you won't be able to dynamically change resolution).
|
||||
- On some platforms such as ARM the first **arguments to a function may be passed via registers**, so it may be better to have fewer parameters in functions.
|
||||
- **Optimize when you already have a working code**. As Donald Knuth put it: "premature optimization is the root of all evil". Nevertheless you should get used to simple nobrainer efficient patterns by default and just write them automatically.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue