marc-mabe / php-enum

Simple and fast implementation of enumerations with native PHP
BSD 3-Clause "New" or "Revised" License
464 stars 36 forks source link

Optimized Enum::byOrdinal() and Enum::getName[s]() #89

Closed marc-mabe closed 7 years ago

marc-mabe commented 7 years ago

…by buffering a list of names per enumeration as Enum::byOrdinal() gets used a lot on EnumSet.

Before:
+----------------+----------------+--------+--------+------+-----+------------+----------+----------+----------+----------+---------+--------+-------------+
| benchmark      | subject        | groups | params | revs | its | mem_peak   | best     | mean     | mode     | worst    | stdev   | rstdev | diff        |
+----------------+----------------+--------+--------+------+-----+------------+----------+----------+----------+----------+---------+--------+-------------+
| EnumBench      | benchGetName   |        | []     | 2500 | 25  | 926,320b   | 21.671μs | 22.576μs | 22.803μs | 23.467μs | 0.478μs | 2.12%  | +5,068.79%  |
| EnumBench      | benchGetNames  |        | []     | 2500 | 25  | 926,320b   | 0.426μs  | 0.437μs  | 0.434μs  | 0.455μs  | 0.008μs | 1.75%  | 0.00%       |
| EnumBench      | benchByOrdinal |        | []     | 2500 | 25  | 926,320b   | 32.392μs | 33.486μs | 32.926μs | 34.850μs | 0.851μs | 2.54%  | +7,566.45%  |
| EnumSet66Bench | benchGetNames  |        | []     | 2000 | 25  | 1,094,920b | 70.176μs | 72.212μs | 72.375μs | 74.549μs | 1.121μs | 1.55%  | +16,432.76% |
| EnumSet32Bench | benchGetNames  |        | []     | 2000 | 25  | 1,032,760b | 31.557μs | 32.471μs | 32.697μs | 33.700μs | 0.499μs | 1.54%  | +7,334.03%  |
+----------------+----------------+--------+--------+------+-----+------------+----------+----------+----------+----------+---------+--------+-------------+

After:
+----------------+----------------+--------+--------+------+-----+------------+----------+----------+----------+----------+---------+--------+-------------+
| benchmark      | subject        | groups | params | revs | its | mem_peak   | best     | mean     | mode     | worst    | stdev   | rstdev | diff        |
+----------------+----------------+--------+--------+------+-----+------------+----------+----------+----------+----------+---------+--------+-------------+
| EnumBench      | benchGetName   |        | []     | 2500 | 25  | 920,848b   | 23.071μs | 23.555μs | 23.477μs | 24.229μs | 0.328μs | 1.39%  | +14,968.33% |
| EnumBench      | benchGetNames  |        | []     | 2500 | 25  | 920,848b   | 0.150μs  | 0.156μs  | 0.156μs  | 0.163μs  | 0.003μs | 1.85%  | 0.00%       |
| EnumBench      | benchByOrdinal |        | []     | 2500 | 25  | 920,848b   | 19.658μs | 20.239μs | 20.012μs | 21.155μs | 0.439μs | 2.17%  | +12,846.93% |
| EnumSet66Bench | benchGetNames  |        | []     | 2000 | 25  | 1,105,864b | 40.634μs | 42.334μs | 41.634μs | 44.363μs | 1.076μs | 2.54%  | +26,981.69% |
| EnumSet32Bench | benchGetNames  |        | []     | 2000 | 25  | 1,036,744b | 20.070μs | 20.812μs | 20.323μs | 21.794μs | 0.624μs | 3.00%  | +13,213.40% |
+----------------+----------------+--------+--------+------+-----+------------+----------+----------+----------+----------+---------+--------+-------------+

PS: The visible performance of Enum::getName() has been decreased a little as the benchmark doesn't has a path where the enumerator knows it's own ordinal number on benchGetName() but a test shows around 7.000μs on my computer :)