performance: Override .elementAt in CachingIterable (#152477)

Add a more efficient override of `Iterable.elementAt` in `CachingIterable`.

Closes #152476
This commit is contained in:
Paolo Lammens 2024-11-01 05:50:17 +01:00 committed by GitHub
parent cadac6bca3
commit d836ca5a68
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 0 deletions

View File

@ -181,6 +181,22 @@ class CachingIterable<E> extends IterableBase<E> {
return _results.length;
}
@override
E elementAt(int index) {
RangeError.checkNotNegative(index, 'index');
while (_results.length <= index) {
if (!_fillNext()) {
throw IndexError.withLength(
index,
_results.length,
indexable: this,
name: 'index',
);
}
}
return _results[index];
}
@override
List<E> toList({ bool growable = true }) {
_precacheEntireList();

View File

@ -107,4 +107,19 @@ void main() {
expect(expanded2, equals(<int>[1, 1, 2, 2, 3, 3, 4, 4, 5, 5]));
expect(yieldCount, equals(5));
});
test('The Caching Iterable: elementAt correctness', () {
final Iterable<int> integers = CachingIterable<int>(range(1, 5).iterator);
expect(yieldCount, equals(0));
expect(() => integers.elementAt(-1), throwsRangeError);
expect(integers.elementAt(1), equals(2));
expect(integers.elementAt(0), equals(1));
expect(integers.elementAt(2), equals(3));
expect(integers.elementAt(4), equals(5));
expect(integers.elementAt(3), equals(4));
expect(() => integers.elementAt(5), throwsRangeError);
});
}