# Wiki

Clone wiki# blaze / Intra-Statement Optimization

One of the prime features of the **Blaze** library is the automatic intra-statement optimization. In order to optimize the overall performance of every single statement **Blaze** attempts to rearrange the operands based on their types. For instance, the following addition of dense and sparse vectors

```
blaze::DynamicVector<double> d1, d2, d3;
blaze::CompressedVector<double> s1;
// ... Resizing and initialization
d3 = d1 + s1 + d2;
```

is automatically rearranged and evaluated as

```
// ...
d3 = d1 + d2 + s1; // <- Note that s1 and d2 have been rearranged
```

This order of operands is highly favorable for the overall performance since the addition of the two dense vectors `d1`

and `d2`

can be handled much more efficiently in a vectorized fashion.

This intra-statement optimization can have a tremendous effect on the performance of a statement. Consider for instance the following computation:

```
blaze::DynamicMatrix<double> A, B;
blaze::DynamicVector<double> x, y;
// ... Resizing and initialization
y = A * B * x;
```

Since multiplications are evaluated from left to right, this statement would result in a matrix/matrix multiplication, followed by a matrix/vector multiplication. However, if the right subexpression is evaluated first, the performance can be dramatically improved since the matrix/matrix multiplication can be avoided in favor of a second matrix/vector multiplication. The **Blaze** library exploits this by automatically restructuring the expression such that the right multiplication is evaluated first:

```
// ...
y = A * ( B * x );
```

Note however that although this intra-statement optimization may result in a measurable or even significant performance improvement, this behavior may be undesirable for several reasons, for instance because of numerical stability. Therefore, in case the order of evaluation matters, the best solution is to be explicit and to separate a statement into several statements:

```
blaze::DynamicVector<double> d1, d2, d3;
blaze::CompressedVector<double> s1;
// ... Resizing and initialization
d3 = d1 + s1; // Compute the dense vector/sparse vector addition first ...
d3 += d2; // ... and afterwards add the second dense vector
```

```
blaze::DynamicMatrix<double> A, B, C;
blaze::DynamicVector<double> x, y;
// ... Resizing and initialization
C = A * B; // Compute the left-hand side matrix-matrix multiplication first ...
y = C * x; // ... before the right-hand side matrix-vector multiplication
```

Alternatively, it is also possible to use the `eval()`

function to fix the order of evaluation:

```
blaze::DynamicVector<double> d1, d2, d3;
blaze::CompressedVector<double> s1;
// ... Resizing and initialization
d3 = d1 + eval( s1 + d2 );
```

```
blaze::DynamicMatrix<double> A, B;
blaze::DynamicVector<double> x, y;
// ... Resizing and initialization
y = eval( A * B ) * x;
```

Previous: Block Vectors and Matrices ---- Next: Frequently Asked Questions (FAQ)

Updated