Skip to content

Conversation

@marc-mabe
Copy link
Owner

@marc-mabe marc-mabe commented Feb 10, 2019

+----------------+-------------------+--------------+--------------------+-----------------------+
| benchmark      | subject           | tag:4.x:mean | tag:generator:mean | tag:newInterator:mean |
+----------------+-------------------+--------------+--------------------+-----------------------+
| EnumSet66Bench | benchIterateFull  | 83.580μs     | 46.399μs           | 100.906μs             |
| EnumSet66Bench | benchIterateEmpty | 0.510μs      | 10.972μs           | 18.026μs              |
| EnumSet32Bench | benchIterateFull  | 33.086μs     | 18.721μs           | 41.721μs              |
| EnumSet32Bench | benchIterateEmpty | 0.401μs      | 3.688μs            | 7.150μs               |
+----------------+-------------------+--------------+--------------------+-----------------------+

Using a Generator makes it even faster iterating through elements of an EnumSet as a direct Iterator implementation.
Instantiating the Generator seems to take more time (and memory) as seen in iterating an empty EnumSet but I think this is reasonable.

But using a generator has some small downsides but in my opinion all of them are negligible:

  • Generator::key() and Generator::current() return NULL on an invalid iterator position
  • Generator::rewind() throw an exception as it's not supported after starting.
  • Additional unused functionalities:
    • Generator::getReturn() - I don't return anything
    • Generator::send - I don't use any return value on yield
    • Generator::throw - I don't expect any exceptions to be thrown
    • Actually I would not phpdoc / return type-hint Generator. Instead I only define Iterator. I would add that as implementation detail on documentation to not expect a Generator returned to be not limited in any feature releases because of that.

ping @prolic

@marc-mabe
Copy link
Owner Author

Even further optimized:

+----------------+-------------------+--------------+--------------------+-----------------------+
| benchmark      | subject           | tag:4.x:mean | tag:generator:mean | tag:newInterator:mean |
+----------------+-------------------+--------------+--------------------+-----------------------+
| EnumSet66Bench | benchIterateFull  | 83.580μs     | 35.053μs           | 100.906μs             |
| EnumSet66Bench | benchIterateEmpty | 0.510μs      | 0.571μs            | 18.026μs              |
| EnumSet32Bench | benchIterateFull  | 33.086μs     | 15.915μs           | 41.721μs              |
| EnumSet32Bench | benchIterateEmpty | 0.401μs      | 0.825μs            | 7.150μs               |
+----------------+-------------------+--------------+--------------------+-----------------------+

@prolic
Copy link
Collaborator

prolic commented Feb 11, 2019

Love it!

Sidenote: Generator::send/throw is mostly used for coroutines in PHP. I didn't encounter any other use case so far, expect to create nice bugs to make people crazy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants