Closed marc-mabe closed 5 years ago
I'm not entirely sure about this. It would make sense only if both classes implement the same Interface. This means the interface would not make sure to handle immutable and mutable objects - in with DateTime and DateTimeImmutable.
Let's fist see what are the performance differences
Here is the full benchmark: master -> 4.x -> 4.x (+ IteratorAggregate) -> 4.x (+IteratorAggregate + Immutable EnumSet)
+----------------+------------------------------+-----------------+--------------+--------------------------------+------------------------------------------+
| benchmark | subject | tag:master:mean | tag:4.x:mean | tag:4.x_IteratorAggregate:mean | tag:4.x_IteratorAggregate_immutable:mean |
+----------------+------------------------------+-----------------+--------------+--------------------------------+------------------------------------------+
| EnumSet66Bench | benchAttachEnumeratorOnEmpty | 29.287μs | 31.747μs | 31.912μs | 41.938μs |
| EnumSet66Bench | benchAttachValueOnEmpty | 58.118μs | 58.716μs | 58.838μs | 74.214μs |
| EnumSet66Bench | benchAttachEnumeratorOnFull | 29.245μs | 31.112μs | 31.922μs | 41.867μs |
| EnumSet66Bench | benchAttachValueOnFull | 58.395μs | 58.506μs | 59.010μs | 73.980μs |
| EnumSet66Bench | benchDetachEnumeratorOnEmpty | 30.443μs | 30.084μs | 30.228μs | 42.689μs |
| EnumSet66Bench | benchDetachValueOnEmpty | 59.323μs | 59.440μs | 59.819μs | 76.255μs |
| EnumSet66Bench | benchDetachEnumeratorOnFull | 30.418μs | 30.235μs | 30.526μs | 42.723μs |
| EnumSet66Bench | benchDetachValueOnFull | 59.539μs | 59.155μs | 59.367μs | 76.757μs |
| EnumSet66Bench | benchContainsEnumeratorTrue | 26.574μs | 31.840μs | 32.317μs | 31.927μs |
| EnumSet66Bench | benchContainsValueTrue | 55.635μs | 58.691μs | 58.582μs | 58.467μs |
| EnumSet66Bench | benchContainsEnumeratorFalse | 26.448μs | 31.883μs | 31.790μs | 31.744μs |
| EnumSet66Bench | benchContainsValueFalse | 55.874μs | 58.790μs | 58.554μs | 58.662μs |
| EnumSet66Bench | benchIterateFull | 82.415μs | 87.251μs | 108.648μs | 108.792μs |
| EnumSet66Bench | benchIterateEmpty | 0.554μs | 0.574μs | 19.426μs | 19.201μs |
| EnumSet66Bench | benchCountFull | 1.445μs | 1.493μs | 1.495μs | 1.504μs |
| EnumSet66Bench | benchCountEmpty | 0.366μs | 0.397μs | 0.397μs | 0.393μs |
| EnumSet66Bench | benchIsEqual | 0.127μs | 0.132μs | 0.132μs | 0.132μs |
| EnumSet66Bench | benchIsSubset | 0.127μs | 0.132μs | 0.132μs | 0.132μs |
| EnumSet66Bench | benchIsSuperset | 0.167μs | 0.178μs | 0.177μs | 0.179μs |
| EnumSet66Bench | benchUnion | 0.265μs | 0.277μs | 0.266μs | 0.267μs |
| EnumSet66Bench | benchIntersect | 0.261μs | 0.274μs | 0.263μs | 0.262μs |
| EnumSet66Bench | benchDiff | 0.291μs | 0.300μs | 0.288μs | 0.292μs |
| EnumSet66Bench | benchSymDiff | 0.263μs | 0.272μs | 0.262μs | 0.263μs |
| EnumSet66Bench | benchGetOrdinalsFull | 3.474μs | 3.544μs | 3.573μs | 3.529μs |
| EnumSet66Bench | benchGetOrdinalsEmpty | 0.377μs | 0.405μs | 0.402μs | 0.402μs |
| EnumSet66Bench | benchGetValues | 33.699μs | 34.179μs | 34.183μs | 34.057μs |
| EnumSet66Bench | benchGetNames | 37.440μs | 38.139μs | 38.276μs | 38.297μs |
| EnumSet66Bench | benchGetEnumerators | 31.761μs | 32.128μs | 32.283μs | 32.001μs |
| EnumBench | benchGetName | 6.588μs | 5.782μs | | |
| EnumBench | benchGetValue | 2.656μs | 2.666μs | | |
| EnumBench | benchGetOrdinal | 3.392μs | 3.845μs | | |
| EnumBench | benchIsByEnumerator | 3.646μs | 4.017μs | | |
| EnumBench | benchIsByValue | 6.419μs | 6.724μs | | |
| EnumBench | benchDetectConstants | 86.766μs | 85.821μs | | |
| EnumBench | benchGetValues | 0.380μs | 0.399μs | | |
| EnumBench | benchGetNames | 0.125μs | 0.131μs | | |
| EnumBench | benchGetOrdinals | 0.395μs | 0.413μs | | |
| EnumBench | benchGetEnumerators | 11.989μs | 11.760μs | | |
| EnumBench | benchByValue | 28.830μs | 29.518μs | | |
| EnumBench | benchByValueAndInitialize | 5,806.739μs | 5,737.836μs | | |
| EnumBench | benchByValueAndInstantiate | 45.060μs | 47.239μs | | |
| EnumBench | benchByName | 9.749μs | 10.237μs | | |
| EnumBench | benchByNameAndInitialize | 73.459μs | 73.974μs | | |
| EnumBench | benchByNameAndInstantiate | 45.595μs | 47.311μs | | |
| EnumBench | benchByOrdinal | 20.823μs | 21.465μs | | |
| EnumBench | benchByOrdinalAndInitialize | 5,823.510μs | 5,730.373μs | | |
| EnumBench | benchByOrdinalAndInstantiate | 32.234μs | 35.153μs | | |
| EnumBench | benchGetByValues | 31.191μs | 32.522μs | | |
| EnumBench | benchGetByEnumerator | 4.712μs | 5.468μs | | |
| EnumBench | benchGetByCallStatic | 18.200μs | 20.783μs | | |
| EnumBench | benchHasByEnumerator | 4.599μs | 5.191μs | | |
| EnumBench | benchHasByValue | 21.604μs | 26.806μs | | |
| EnumSet32Bench | benchAttachEnumerator | 10.562μs | 11.244μs | 11.198μs | 14.889μs |
| EnumSet32Bench | benchAttachValue | 21.685μs | 22.114μs | 22.232μs | 27.641μs |
| EnumSet32Bench | benchDetachEnumerator | 10.788μs | 11.335μs | 11.529μs | 14.994μs |
| EnumSet32Bench | benchDetachValue | 21.999μs | 22.602μs | 22.463μs | 28.013μs |
| EnumSet32Bench | benchContainsEnumeratorTrue | 10.575μs | 11.804μs | 11.756μs | 11.773μs |
| EnumSet32Bench | benchContainsEnumeratorFalse | 10.544μs | 11.802μs | 11.773μs | 11.782μs |
| EnumSet32Bench | benchContainsValueTrue | 21.563μs | 23.346μs | 23.199μs | 23.186μs |
| EnumSet32Bench | benchContainsValueFalse | 21.615μs | 23.257μs | 23.307μs | 23.158μs |
| EnumSet32Bench | benchIterateFull | 33.523μs | 35.523μs | 46.422μs | 46.495μs |
| EnumSet32Bench | benchIterateEmpty | 0.401μs | 0.416μs | 7.837μs | 7.834μs |
| EnumSet32Bench | benchCountFull | 0.663μs | 0.717μs | 0.717μs | 0.720μs |
| EnumSet32Bench | benchCountEmpty | 0.193μs | 0.207μs | 0.208μs | 0.208μs |
| EnumSet32Bench | benchIsEqual | 0.159μs | 0.165μs | 0.164μs | 0.164μs |
| EnumSet32Bench | benchIsSubset | 0.159μs | 0.165μs | 0.164μs | 0.164μs |
| EnumSet32Bench | benchIsSuperset | 0.144μs | 0.159μs | 0.159μs | 0.160μs |
| EnumSet32Bench | benchUnion | 0.260μs | 0.263μs | 0.253μs | 0.253μs |
| EnumSet32Bench | benchIntersect | 0.257μs | 0.264μs | 0.253μs | 0.257μs |
| EnumSet32Bench | benchDiff | 0.256μs | 0.264μs | 0.255μs | 0.257μs |
| EnumSet32Bench | benchSymDiff | 0.254μs | 0.266μs | 0.254μs | 0.254μs |
| EnumSet32Bench | benchGetOrdinalsFull | 1.181μs | 1.240μs | 1.228μs | 1.237μs |
| EnumSet32Bench | benchGetOrdinalsEmpty | 0.707μs | 0.723μs | 0.722μs | 0.719μs |
| EnumSet32Bench | benchGetValues | 15.968μs | 16.170μs | 16.176μs | 16.176μs |
| EnumSet32Bench | benchGetNames | 17.735μs | 18.261μs | 18.228μs | 18.257μs |
| EnumSet32Bench | benchGetEnumerators | 14.946μs | 15.354μs | 15.308μs | 15.315μs |
| EnumMapBench | benchGetKeysEmpty | 0.395μs | 0.400μs | | |
| EnumMapBench | benchGetKeysFull | 23.008μs | 22.944μs | | |
| EnumMapBench | benchGetValuesEmpty | 0.081μs | 0.088μs | | |
| EnumMapBench | benchGetValuesFull | 0.082μs | 0.089μs | | |
| EnumMapBench | benchSearchTypeJuggling | 1.418μs | 1.458μs | | |
| EnumMapBench | benchSearchStrict | 0.671μs | 0.718μs | | |
| EnumMapBench | benchOffsetSetEnumerator | 21.533μs | 24.604μs | | |
| EnumMapBench | benchOffsetSetValue | 47.017μs | 49.960μs | | |
| EnumMapBench | benchOffsetUnsetEnumerator | 18.890μs | 19.882μs | | |
| EnumMapBench | benchOffsetUnsetValue | 45.957μs | 47.261μs | | |
| EnumMapBench | benchOffsetExistsEnumerator | 17.477μs | 18.851μs | | |
| EnumMapBench | benchOffsetExistsValue | 44.923μs | 47.916μs | | |
| EnumMapBench | benchContainsEnumerator | 19.162μs | 22.397μs | | |
| EnumMapBench | benchContainsValue | 45.832μs | 47.982μs | | |
| EnumMapBench | benchIterateFull | 56.906μs | 58.628μs | | |
| EnumMapBench | benchIterateEmpty | 0.219μs | 0.224μs | | |
| EnumMapBench | benchCountFull | 0.086μs | 0.090μs | | |
| EnumMapBench | benchCountEmpty | 0.086μs | 0.090μs | | |
+----------------+------------------------------+-----------------+--------------+--------------------------------+------------------------------------------+
For me it tells me I should check where all the performance degrations comes from.
master -> 4.x
it could be based on type-hints - I'll check if I can remove at least some of them - they are documented anyway and this lib does extensible testing.IteratorAggregate
it seams clear that this approach is much slower then a direct Iterator. It was clear from the beginning but the difference is a lot. I'll do some tests with generators nowimmutable EnumSet
- this was expected and does not seem too bad. I'll also add a methods to add/remove enumerators based on a given iterable
and also think of accepting this as constructor argument as then the with[out]Enumerator
methods should be needed in much rare cases.@prolic It's ready now :)
I decided to have both mutable and immutable interfaces but with consistent naming:
EnumSet
with an iterable list of enumerators[attach|detach]
-> [attach|detach]Enumerator
[attach|detach]Enumerators
withEnumerator
& withEnumerators
withoutEnumerator
& withoutEnumerators
withBinaryBitset[Le|Be]
withBit
union
-> withUnion
setUnion
intersect
-> withIntersect
setIntersect
diff
-> withDiff
setDiff
symDiff
-> withSymDiff
setSymDiff
Based on #108
EnumSet
as immutableattach(): void
->withEnumerator(): self
detach(): void
->withoutEnumerator(): self
setBit(): void
->withBit(): self
setBinaryBitset[Le|Be](): void
->withBinaryBitset[Le|Be](): self
PS 1: I still want to make some benchmarks for comparison PS 2: This make sense only if we make
EnumMap
immutable too@prolic ping