# Performance tricks§

**nalgebra** defines a few types that may save you valuable computation times.
Those types have strong restrictions in their use and have a quite narrow
semantic. However, they can sometimes save you a few square roots, corner-cases
checking, or even avoid costly matrix multiplications.

## The `Unit`

wrapper§

Many geometrical algorithms require some of its inputs to have a unit norm.
For example the normal of a triangle or a quaternion that represents a 3D
rotation should have a magnitude equal to 1. That’s why the `Unit`

wrapper type
is here to ensure that the underlying value has a unit norm. For example
`Unit<Vector3<f32>>`

is a normalized 3D vector, i.e., it lies on the unit
3-dimensional sphere . Also note that the `UnitQuaternion<T>`

representing a 3D rotation is actually a type alias for `Unit<Quaternion<T>>`

.
In general, the `Unit`

wrapper should be used whenever you write an algorithm
that expects a normalized direction as an input. Doing so, you avoid the need
to normalize the input vector yourself and don’t have to deal with special
cases where the given direction is zero. Here is a simple example that computes
the length of one vector along a given direction:

```
fn length_on_direction(v: &Vector3<f32>, dir: &Unit<Vector3<f32>>) -> f32 {
// No need to normalize `dir`: we know that it is non-zero and normalized.
na::dot(v, dir.as_ref())
}
```

```
fn length_on_direction(v: &Vector3<f32>, dir: &Vector3<f32>) -> f32 {
// Obligatory normalization of the direction vector (and test, for robustness).
if let Some(unit_dir) = dir.try_normalize(1.0e-6) {
na::dot(v, &unit_dir)
}
else {
// Normalization failed because the norm was too small.
panic!("Invalid input direction.")
}
}
```

## The `Id`

type§

The `Id`

type (re-exported from the `alga`

crate) represents the identity
element of any operator for any algebraic entity. In practice, all its
operations are no-ops. While using this where all types are explicitly known
might seem useless, it can save performances in generic code. Indeed, `Id`

implements all transformation traits from the `alga`

crate: `Translation`

,
`Rotation`

, `Transformation`

etc. Thus, a generic algorithm that performs lots
of multiplication by a transformation given in input will benefit from the fact
that `Id`

does all of them for free. In other words, passing `Id`

instead of,
say, `Rotation3::<f32>::identity()`

, to a generic function will avoid useless
matrix multiplications.

```
/*
* Applies `n` times the transformation `t` to the vector `v` and sum each
* intermediate value.
*/
fn complicated_algorithm<T>(v: &Vector3<f32>, t: &T, n: usize) -> Vector3<f32>
where T: Transformation<Point3<f32>> {
let mut result = *v;
// Do lots of operations involving t.
for _ in 0 .. n {
result = v + t.transform_vector(&result);
}
result
}
/*
* The two following calls are equivalent in term of result.
*/
fn main() {
let v = Vector3::new(1.0, 2.0, 3.0);
// The specialization generated by the compiler will do vector additions only.
let result1 = complicated_algorithm(&v, &Id::new(), 100000);
// The specialization generated by the compiler will also include matrix multiplications.
let iso = Isometry3::identity();
let result2 = complicated_algorithm(&v, &iso, 100000);
// They both return the same result.
assert!(result1 == Vector3::new(100001.0, 200002.0, 300003.0));
assert!(result2 == Vector3::new(100001.0, 200002.0, 300003.0));
}
```