# Performance¶

Here are a few comparisons between the data types provided by pgmp and the builtin PostgreSQL data types. A few observations:

Of course

`mpz`

is not a substitute for`decimal`

as it doesn’t store the non-integer part. So yes, we are comparing apples with pineapples, but`decimal`

is the only currently available way to have arbitrary size numbers in PostgreSQL.We don’t claim the extra speed summing numbers with 1000 digits is something everybody needs, nor that applications doing a mix of math and other operations or under an I/O load will benefit of the same speedup.

Those are “laptop comparisons”, not obtained with a tuned PostgreSQL installation nor on production-grade hardware. However they are probably fine enough to compare the difference in behaviour between the data types, and I expect the same performance ratio on different hardware with the same platform.

All the results are obtained using the scripts available in the bench directory of the pmpz source code.

Just taking the sum of a table with 1M records, `mpz`

is about 25% faster than
`numeric`

for small numbers; the difference increases with the size of the
number up to about 75% for numbers with 1000 digits. `int8`

is probably
slower than `numeric`

because the numbers are cast to `numeric`

before
calculation. `int4`

is casted to `int8`

instead, so it still benefits of the
speed of a native datatype. `mpq`

behaves good as no canonicalization has to
be performed.

Performing a mix of operations the differences becomes more noticeable. This
plot shows the time taken to calculate sum(a + b * c / d) on a 1M records
table. `mpz`

is about 45% faster for small numbers, up to 80% faster for
numbers with 100 digits. `int8`

is not visible as perfectly overlapping
`mpz`

. `mpq`

is not shown as out of scale (a test with smaller table reveals
a quadratic behavior probably due to the canonicalization).

The difference in performance of multiplications is particularly evident: Here
is a test calculating *n*! in a trivial way (performing the product of a
sequence of numbers via a *product* aggregate function defined in SQL).
The time taken to calculate 10000! via repeated `mpz`

multiplications is
about 40 ms.

These comparisons show the perfomance with a sum of the same values stored in
`mpq`

and `decimal`

. Because these rationals are representation of numbers
with finite decimal expansion, the denominator doesn’t grow unbounded (as in
sum(1/n) on a sequence of random numbers) but is capped by 10^scale.
`decimal`

is pretty stable in its performance for any scale but the time
increases markedly with the precision (total number of digits). `mpq`

grows
way more slowly with the precision, but has a noticeable overhead increasing
with the scale.

Here is a comparison of the size on disk of tables containing 1M records of
different data types. The numbers are integers, so there is about a constant
offset between `mpz`

and `mpq`

. The platform is 32 bit.