With PHP 5.5 now set as the minimum it is possible to use generators.
http://php.net/manual/en/language.generators.overview.php
Quoting from the PHP manual:
Generators provide an easy way to implement simple iterators without the overhead or complexity of implementing a class that implements the Iterator interface.
A generator allows you to write code that uses foreach to iterate over a set of data without needing to build an array in memory, which may cause you to exceed a memory limit, or require a considerable amount of processing time to generate. Instead, you can write a generator function, which is the same as a normal function, except that instead of returning once, a generator can yield as many times as it needs to in order to provide the values to be iterated over.
I'm personally interested in writing code using this mechanic, but what areas of the code could best benefit from this switch.
This ticket shares its parent's priority and tags.
Comments
Comment #1
dawehnerWhy I would really encourage us to use the yield statement in general (potentially even for more than just generators)
I can't see why this should be critical. Would you release without it?
https://nikic.github.io/2012/12/22/Cooperative-multitasking-using-corout... is a great blog post about the yield statement and that generators are just the start.
Comment #2
Aki Tendo CreditAttribution: Aki Tendo commentedI was merely mirroring the parent's tags and priority level. Sorry.
Comment #3
dawehnerNo problem. To be clear generators are not the holy grail in performance, I mean, if you need to do the same kind of work and you are not creating HUGE amount of data to even get started with your foreaches, yields not necessarily safe you anything but even make it worse.
Comment #4
Crell CreditAttribution: Crell at Palantir.net commentedI don't know how much runtime performance generators would gain us. I'd expect it more to save us lines of code, if we find places to use it.
I'm all for using generators if we find a place for them, but I don't know that there's any significant CPU benefit...
Comment #5
tim.plunkettNone of these are demonstrably applicable.
Comment #6
pounardMostly generators can make you gain memory when iterating over very large result sets, depending on what's your source. But it certainly would be a good idea in DBTNG, in some cases I guess, pretty much anywhere where you iterate over SQL results to modify the data and return some array, you can just iterate over a generator instead without creating ever the intermediate array. It may also just avoid creating two arrays in the first place...
Comment #7
twistor CreditAttribution: twistor as a volunteer commented@pounard, yeah that. I can see possible memory savings, but I very much doubt any performance gains.
Comment #8
pounardIterating only once is better than twice, and even if the gain is minimal, it's still a good school use case, I guess it might not worth the shot of chasing those use case except for pure fun, but it's would be definitely logical to convert them as you see it.
Comment #9
Crell CreditAttribution: Crell at Palantir.net commentedSo are there specific places in code we can suggest? This meta discussion isn't that helpful until we see some examples.
DB result handling is almost always just a PDOStatement object, which is a C-level object that's already traversable so there's not much more for us to do in general...
Comment #10
pounardThere actually is a few methods which are build an intermediate array, such as
fetchAllAssoc()
andfetchAllKeyed()
, but they are the only one I could find, and for those two I don't think a generated would gain much since most people will probably use the result as-is.Comment #11
Crell CreditAttribution: Crell at Palantir.net commentedYeah, fetchAllAssoc() is intended for use when you want random lookup, and fetchAllKeyed() is generally added directly to a form array as-is. A generator wouldn't work for either of those.
Any others? Anywhere in core?
Comment #23
quietone CreditAttribution: quietone at PreviousNext commentedMore information was asked here seven years ago and none has been provided. That is, no specific places where code should be changed to use yield. And yield is being used in core now.
I think this can be closed as outdated, because yield is now used in core as needed.