Re: RFC: CachedIterable (rewindable, allows any key&repeating keys)
| From: | tyson andre | Date: | Fri, 12 Feb 2021 18:19:35 +0000 |
| Subject: | Re: RFC: CachedIterable (rewindable, allows any key&repeating keys) | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-113157@lists.php.net to get a copy of this message | ||
Hi Alex,
> > I've created a new RFC
> > https://wiki.php.net/rfc/cachediterable adding CachedIterable,
> > which eagerly evaluates any iterable and contains an immutable copy of the keys and values
> > of the iterable it was constructed from
> >
> >
> > Any other feedback unrelated to namespaces?
>
> Hi Tyson,
>
> I needed this feature a few years ago. In that case, the source was a generator that was slowly
> generating data while fetching them from a paginated API that had rate limits.
> The result wrapping iterator was used at runtime in multiple (hundreds) other iterators that
> were processing elements in various ways (technical analysis indicator on time series) and after
> that merged back with some MultipleIterator.
>
> Just for reference, this is how the implementation in userland was and I was happy with it as a
> solution:
>
> https://gist.github.com/drealecs/ad720b51219675a8f278b8534e99d7c7
>
> Not sure if it's useful but I thought I should share it as I noticed you mentioned in your
> example for PolyfillIterator you chose not to use an IteratorAggregate because complexity
> Was wondering how much inefficient this would be compared to the C implementation.
That was for simplicity(shortness) of the RFC for people reading the polyfill.
I don't expect it to affect CPU timing or memory usage for large arrays in the polyfill.
Userland lazy iterable implementations could still benefit from having a CachedIterable around,
by replacing the lazy IteratorAggregate with a Cached Iterable when the end of iteration was
detected.
> Also, the implementation having the ability to be lazy was important and I think that should be
> the case here as well, by design, especially as we are dealing with Generators.
We're dealing with the entire family of iterables, including but not limited to Generators,
arrays, user-defined Traversables, etc.
I'd considered that but decided not to include it in the RFC's scope.
If I was designing that, it would be a separate class
LazyCachedIterable.
Currently, CachedIterable has several useful properties:
1. Serialization/Unserializable behavior is predictable - if the object was constructed it can be
safely serialized if keys/values can be serialized.
2. Iteration has no side effects (e.g. won't throw)
3. keyAt(int $offset) and so on have predictable behavior, good performance, and only one throwable
type
4. Memory usage is small - this might also be the case for a LazyIterable depending on
implementation choices/constraints.
Adding lazy iteration support would make it no longer have some of those properties.
While I'd be in favor of that if it was implemented correctly, I don't plan to work on
implementing this until I know
if the addition of CachedIterable to a large family of iterable classes would pass.
CachedIterable has some immediate benefits on problems I was actively working on, such as:
1. Being able to represent iterable functions such as iterable_reverse()
2. Memory efficiency and time efficiency for iteration
3. Being something internal code could return for getIterator(), etc.
Regards,
Tyson