# Don't compute it twice The example I am going to present will make some of you react like this: ![really](img/really.jpg) I say this because it will be absolutely obvious... in retrospective. On the other hand, I have seen **this same code** being used in multiple open source projects. Projects with hundreds of Github stars missed this (apparently obvious) opportunity for optimization. A notable example is: [Speed up improvement for laserOdometry and scanRegister (20%)](https://github.com/laboshinl/loam_velodyne/pull/20) ## 2D transforms Let's consider this code: ```c++ double x1 = x*cos(ang) - y*sin(ang) + tx; double y1 = x*sin(ang) + y*cos(ang) + ty; ``` People with a trained eye (and a little of trigonometric background) will immediately recognize the [affine transform of a 2D point], commonly used in computer graphics and robotics. Don't you see anything we can do better? Of course: ```c++ const double Cos = cos(angle); const double Sin = sin(angle); double x1 = x*Cos - y*Sin + tx; double y1 = x*Sin + y*Cos + ty; ``` The cost of trigonometric functions is relatively high and there is absolutely no reason to compute twice the same value. The latter code will be 2x times faster then the former, because the cost of multiplication and sum is really low compared with `sin()` and `cos()`. In general, if the number of potential angles you need to test is not extremely high, consider to use look-up-table where you can store pre-computed values. This is the case, for instance, of laser scan data, that needs to be converted from polar coordinates to cartesian ones. ![laser_scan_matcher.png](img/laser_scan_matcher.png) A naive implementation would invoke trigonometric functions for each point (in the order of thousands per seconds). ```c++ // Conceptual operation (inefficient) // Data is usually stored in a vector of distances std::vector scan_distance; // the input std::vector cartesian_points; // the output cartesian_points.reserve( scan_distance.size() ); for(int i=0; i LUT_cos; std::vector LUT_sin; for(int i=0; i scan_distance; std::vector cartesian_points; cartesian_points.reserve( scan_distance.size() ); for(int i=0; i