Integrated: 8329331: Intrinsify Unsafe::setMemory
On Fri, 29 Mar 2024 22:32:06 GMT, Scott Gibbons wrote: > This code makes an intrinsic stub for `Unsafe::setMemory` for x86_64. See > [this PR](https://github.com/openjdk/jdk/pull/16760) for discussion around > this change. > > Overall, making this an intrinsic improves overall performance of > `Unsafe::setMemory` by up to 4x for all buffer sizes. > > Tested with tier-1 (and full CI). I've added a table of the before and after > numbers for the JMH I ran (`MemorySegmentZeroUnsafe`). > > [setMemoryBM.txt](https://github.com/openjdk/jdk/files/14808974/setMemoryBM.txt) This pull request has now been integrated. Changeset: bd67ac69 Author:Scott Gibbons Committer: Jatin Bhateja URL: https://git.openjdk.org/jdk/commit/bd67ac69a234cd1096e534c7d4a45d88715884b4 Stats: 507 lines in 36 files changed: 420 ins; 5 del; 82 mod 8329331: Intrinsify Unsafe::setMemory Reviewed-by: sviswanathan, jbhateja, kvn - PR: https://git.openjdk.org/jdk/pull/18555
Re: RFR: 8329331: Intrinsify Unsafe::setMemory [v26]
On Sat, 20 Apr 2024 22:31:48 GMT, Scott Gibbons wrote: >> This code makes an intrinsic stub for `Unsafe::setMemory` for x86_64. See >> [this PR](https://github.com/openjdk/jdk/pull/16760) for discussion around >> this change. >> >> Overall, making this an intrinsic improves overall performance of >> `Unsafe::setMemory` by up to 4x for all buffer sizes. >> >> Tested with tier-1 (and full CI). I've added a table of the before and >> after numbers for the JMH I ran (`MemorySegmentZeroUnsafe`). >> >> [setMemoryBM.txt](https://github.com/openjdk/jdk/files/14808974/setMemoryBM.txt) > > Scott Gibbons has updated the pull request with a new target base due to a > merge or a rebase. The pull request now contains 37 commits: > > - Merge branch 'openjdk:master' into setMemory > - Fix UnsafeCopyMemoryMark scope issue > - Long to short jmp; other cleanup > - Review comments > - Address review comments; update copyright years > - Add enter() and leave(); remove Windows-specific register stuff > - Fix memory mark after sync to upstream > - Merge branch 'openjdk:master' into setMemory > - Set memory test (#23) > >* Even more review comments > >* Re-write of atomic copy loops > >* Change name of UnsafeCopyMemory{,Mark} to UnsafeMemory{Access,Mark} > >* Only add a memory mark for byte unaligned fill > >* Remove MUSL_LIBC ifdef > >* Remove MUSL_LIBC ifdef > - Set memory test (#22) > >* Even more review comments > >* Re-write of atomic copy loops > >* Change name of UnsafeCopyMemory{,Mark} to UnsafeMemory{Access,Mark} > >* Only add a memory mark for byte unaligned fill > - ... and 27 more: https://git.openjdk.org/jdk/compare/6d569961...1122b500 Marked as reviewed by jbhateja (Reviewer). - PR Review: https://git.openjdk.org/jdk/pull/18555#pullrequestreview-2013564907
Integrated: 8318650: Optimized subword gather for x86 targets.
On Wed, 25 Oct 2023 04:34:59 GMT, Jatin Bhateja wrote: > Hi All, > > This patch optimizes sub-word gather operation for x86 targets with AVX2 and > AVX512 features. > > Following is the summary of changes:- > > 1) Intrinsify sub-word gather using hybrid algorithm which initially > partially unrolls scalar loop to accumulates values from gather indices into > a quadword(64bit) slice followed by vector permutation to place the slice > into appropriate vector lanes, it prevents code bloating and generates > compact JIT sequence. This coupled with savings from expansive array > allocation in existing java implementation translates into significant > performance of 1.5-10x gains with included micro. > > ![image](https://github.com/openjdk/jdk/assets/59989778/e25ba4ad-6a61-42fa-9566-452f741a9c6d) > > > 2) Patch was also compared against modified java fallback implementation by > replacing temporary array allocation with zero initialized vector and a > scalar loops which inserts gathered values into vector. But, vector insert > operation in higher vector lanes is a three step process which first extracts > the upper vector 128 bit lane, updates it with gather subword value and then > inserts the lane back to its original position. This makes inserts into > higher order lanes costly w.r.t to proposed solution. In addition generated > JIT code for modified fallback implementation was very bulky. This may impact > in-lining decisions into caller contexts. > > Kindly review and share your feedback. > > Best Regards, > Jatin This pull request has now been integrated. Changeset: 185e711b Author:Jatin Bhateja URL: https://git.openjdk.org/jdk/commit/185e711bfe4c4d013b56e867f85cfb4177b3a2cf Stats: 1178 lines in 32 files changed: 1129 ins; 21 del; 28 mod 8318650: Optimized subword gather for x86 targets. Reviewed-by: sviswanathan, epeter, psandoz - PR: https://git.openjdk.org/jdk/pull/16354
Re: RFR: 8329331: Intrinsify Unsafe::setMemory [v26]
On Sat, 20 Apr 2024 22:31:48 GMT, Scott Gibbons wrote: >> This code makes an intrinsic stub for `Unsafe::setMemory` for x86_64. See >> [this PR](https://github.com/openjdk/jdk/pull/16760) for discussion around >> this change. >> >> Overall, making this an intrinsic improves overall performance of >> `Unsafe::setMemory` by up to 4x for all buffer sizes. >> >> Tested with tier-1 (and full CI). I've added a table of the before and >> after numbers for the JMH I ran (`MemorySegmentZeroUnsafe`). >> >> [setMemoryBM.txt](https://github.com/openjdk/jdk/files/14808974/setMemoryBM.txt) > > Scott Gibbons has updated the pull request with a new target base due to a > merge or a rebase. The pull request now contains 37 commits: > > - Merge branch 'openjdk:master' into setMemory > - Fix UnsafeCopyMemoryMark scope issue > - Long to short jmp; other cleanup > - Review comments > - Address review comments; update copyright years > - Add enter() and leave(); remove Windows-specific register stuff > - Fix memory mark after sync to upstream > - Merge branch 'openjdk:master' into setMemory > - Set memory test (#23) > >* Even more review comments > >* Re-write of atomic copy loops > >* Change name of UnsafeCopyMemory{,Mark} to UnsafeMemory{Access,Mark} > >* Only add a memory mark for byte unaligned fill > >* Remove MUSL_LIBC ifdef > >* Remove MUSL_LIBC ifdef > - Set memory test (#22) > >* Even more review comments > >* Re-write of atomic copy loops > >* Change name of UnsafeCopyMemory{,Mark} to UnsafeMemory{Access,Mark} > >* Only add a memory mark for byte unaligned fill > - ... and 27 more: https://git.openjdk.org/jdk/compare/6d569961...1122b500 Thank you all for the reviews. - PR Comment: https://git.openjdk.org/jdk/pull/18555#issuecomment-2068196116
Re: RFR: 8329331: Intrinsify Unsafe::setMemory [v26]
On Sat, 20 Apr 2024 22:31:48 GMT, Scott Gibbons wrote: >> This code makes an intrinsic stub for `Unsafe::setMemory` for x86_64. See >> [this PR](https://github.com/openjdk/jdk/pull/16760) for discussion around >> this change. >> >> Overall, making this an intrinsic improves overall performance of >> `Unsafe::setMemory` by up to 4x for all buffer sizes. >> >> Tested with tier-1 (and full CI). I've added a table of the before and >> after numbers for the JMH I ran (`MemorySegmentZeroUnsafe`). >> >> [setMemoryBM.txt](https://github.com/openjdk/jdk/files/14808974/setMemoryBM.txt) > > Scott Gibbons has updated the pull request with a new target base due to a > merge or a rebase. The pull request now contains 37 commits: > > - Merge branch 'openjdk:master' into setMemory > - Fix UnsafeCopyMemoryMark scope issue > - Long to short jmp; other cleanup > - Review comments > - Address review comments; update copyright years > - Add enter() and leave(); remove Windows-specific register stuff > - Fix memory mark after sync to upstream > - Merge branch 'openjdk:master' into setMemory > - Set memory test (#23) > >* Even more review comments > >* Re-write of atomic copy loops > >* Change name of UnsafeCopyMemory{,Mark} to UnsafeMemory{Access,Mark} > >* Only add a memory mark for byte unaligned fill > >* Remove MUSL_LIBC ifdef > >* Remove MUSL_LIBC ifdef > - Set memory test (#22) > >* Even more review comments > >* Re-write of atomic copy loops > >* Change name of UnsafeCopyMemory{,Mark} to UnsafeMemory{Access,Mark} > >* Only add a memory mark for byte unaligned fill > - ... and 27 more: https://git.openjdk.org/jdk/compare/6d569961...1122b500 My testing passed. Good. - Marked as reviewed by kvn (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/18555#pullrequestreview-2013478795
Re: EnumeratedStream
To clear things up, Issues are related to handling using type erasure, not class generating approach. вс, 21 апр. 2024 г. в 18:45, ІП-24 Олександр Ротань < rotan.olexa...@gmail.com>: > To clear thing up, Issues are related to handling using type erasure, not > class generating approach. > > вс, 21 апр. 2024 г. в 16:48, ІП-24 Олександр Ротань < > rotan.olexa...@gmail.com>: > >> I am not really familiar with goals and milestones of Valhalla project, >> but what I meant by simplification is that there would not be any more need >> to convert to promotove streams explicitly as Stream would be a >> thing. If that's what Valhalla is working on, then this would be just >> great. Performance concerns regarding wrappers are also valid , but here >> I am talking about implementation complexity. >> >> If going little off topic, compiling many classes to achieve generic >> reification in fact looks odd, but it in fact provides best developer >> experience, Converting primitive arrays to collections is one of the >> examples of major problems issues with it, along with some methods of >> Arrays class (like sort, if I am not mistaken), just don't work with >> primitives.Approach that is used in C#, while has its downsides, provides >> much better user experience. However, what I am looking into right now is >> some hybrid form of generic handling, where generic maybe be reified on >> demand of developer (or implicitly if primitive is used). I am working on >> some prototypes at the moment >> >> вс, 21 апр. 2024 г. в 16:31, - : >> >>> On Sun, Apr 21, 2024 at 5:49 AM ІП-24 Олександр Ротань < >>> rotan.olexa...@gmail.com> wrote: >>> I have heard your proposal. Your approach indeed for sure has its advantages. One thing I don't like referring to is Valhalla. It's not even a preview and no one really knows when it will be, relying on it when designing API now would be strange to say the least. >>> Valhalla's value classes are actually quite ready; the compatibility and >>> the type system are quite fleshed out in the recent iterations, and the >>> prototypes are already functional. >>> One possible thing that could dramatically simplify implementation of my approach is introduction of generic reification, which would allow primitives as type params. I am currently studying the working of javac and possible implementation of this is one of the topics in my research. However, let's stick to what we have in jdk right now from now on. >>> Generic reification is part of project Valhalla too, in that it allows >>> wrapper classes in generics to have the same performance as the primitives >>> with generic specialization. Compiling many classes to achieve generic >>> reification is an alternative, but I don't think it's feasible. >>> I would like to hear opinions of other people regarding the design of such API, especially David and Remi, since, as I understand, that's not the first time they witness a discussion like this, so maybe they have something to tell here. >>> Unfortunately you will have to wait. Most JDK engineers are employees >>> who work on weekdays; only a few are enthusiasts. I think we may get more >>> discussion traffic on Monday. >>> >>
Re: RFR: 8266431: Dual-Pivot Quicksort improvements (Radix sort) [v11]
On Sun, 21 Apr 2024 04:37:45 GMT, Srinivas Vamsi Parasa wrote: >> Hello Vamsi (@vamsi-parasa), >> >> Could you please run the new benchmarking? >> To save time and don't patch JDK several times, I've created >> JavaBenchmarkHarness >> class which is under package java.util and compares several versions of DPQS. >> Also I prepared several versions of current sorting source from JDK to >> detect what is going wrong. >> >> What you need is to compile and run JavaBenchmarkHarness once: >> >> javac --patch-module java.base=. -d classes *.java >> java -XX:CompileThreshold=1 -XX:-TieredCompilation --patch-module >> java.base=classes -cp classes java.util.JavaBenchmarkHarness >> >> Find the sources there: >> >> https://github.com/iaroslavski/sorting/blob/master/radixsort/JavaBenchmarkHarness.java >> >> https://github.com/iaroslavski/sorting/blob/master/radixsort/DualPivotQuicksort_b01.java >> https://github.com/iaroslavski/sorting/blob/master/radixsort/DualPivotQuicksort_b01_ins.java >> https://github.com/iaroslavski/sorting/blob/master/radixsort/DualPivotQuicksort_b01_mrg.java >> https://github.com/iaroslavski/sorting/blob/master/radixsort/DualPivotQuicksort_b01_piv.java >> https://github.com/iaroslavski/sorting/blob/master/radixsort/DualPivotQuicksort_b01_prt.java >> https://github.com/iaroslavski/sorting/blob/master/radixsort/DualPivotQuicksort_r29p.java >> https://github.com/iaroslavski/sorting/blob/master/radixsort/DualPivotQuicksort_r29p5.java >> >> Thank you, >> Vladimir > > Hi Vladimir (@iaroslavski), > > Please see the data below: > > Thanks, > Vamsi > > > > name | builder | size | mode | count | score > -- | -- | -- | -- | -- | -- > b01 | RANDOM | 600 | avg | 325677 | 6.862 > b01 | RANDOM | 3000 | avg | 52041 | 82.233 > b01 | RANDOM | 9 | avg | 1217 | 4456.51 > b01 | RANDOM | 40 | avg | 242 | 22923.28 > b01 | RANDOM | 100 | avg | 90 | 60598.84 > b01 | REPEATED | 600 | avg | 651354 | 1.933 > b01 | REPEATED | 3000 | avg | 104083 | 13.753 > b01 | REPEATED | 9 | avg | 2435 | 723.039 > b01 | REPEATED | 40 | avg | 484 | 3084.416 > b01 | REPEATED | 100 | avg | 180 | 8234.428 > b01 | STAGGER | 600 | avg | 1954062 | 1.005 > b01 | STAGGER | 3000 | avg | 312251 | 4.945 > b01 | STAGGER | 9 | avg | 7305 | 133.126 > b01 | STAGGER | 40 | avg | 1453 | 592.144 > b01 | STAGGER | 100 | avg | 542 | 1493.876 > b01 | SHUFFLE | 600 | avg | 325677 | 5.12 > b01 | SHUFFLE | 3000 | avg | 52041 | 29.252 > b01 | SHUFFLE | 9 | avg | 1217 | 1396.664 > b01 | SHUFFLE | 40 | avg | 242 | 5743.489 > b01 | SHUFFLE | 100 | avg | 90 | 15490.81 > b01_ins | RANDOM | 600 | avg | 325677 | 7.594 > b01_ins | RANDOM | 3000 | avg | 52041 | 78.631 > b01_ins | RANDOM | 9 | avg | 1217 | 4312.511 > b01_ins | RANDOM | 40 | avg | 242 | 22108.18 > b01_ins | RANDOM | 100 | avg | 90 | 58467.16 > b01_ins | REPEATED | 600 | avg | 651354 | 1.569 > b01_ins | REPEATED | 3000 | avg | 104083 | 11.313 > b01_ins | REPEATED | 9 | avg | 2435 | 720.838 > b01_ins | REPEATED | 40 | avg | 484 | 3003.673 > b01_ins | REPEATED | 100 | avg | 180 | 8144.944 > b01_ins | STAGGER | 600 | avg | 1954062 | 0.98 > b01_ins | STAGGER | 3000 | avg | 312251 | 4.948 > b01_ins | STAGGER | 9 | avg | 7305 | 132.909 > b01_ins | STAGGER | 40 | avg | 1453 | 592.572 > b01_ins | STAGGER | 100 | avg | 542 | 1492.627 > b01_ins | SHUFFLE | 600 | avg | 325677 | 4.092 > b01_ins | SHUFFLE | 3000 | avg | 52041 | 27.138 > b01_ins | SHUFFLE | 9 | avg | 1217 | 1304.326 > b01_ins | SHUFFLE | 40 | avg | 242 | 5465.745 > b01_ins | SHUFFLE | 100 | avg | 90 | 14585.08 > b01_mrg | RANDOM | 600 | avg | 325677 | 7.139 > b01_mrg | RANDOM | 3000 | avg | 52041 | 81.01 > b01_mrg | RANDOM | 9 | avg | 1217 | 4266.084 > b01_mrg | RANDOM | 40 | avg | 242 | 21937.77 > b01_mrg | RANDOM | 100 | avg | 90 | 58177.72 > b01_mrg | REPEATED | 600 | avg | 651354 | 1.36 > b01_mrg | REPEATED | 3000 | avg | 104083 | 9.013 > b01_mrg | REPEATED | 9 | avg | 2435 | 737.684 > b01_mrg | REPEATED | 40 | avg | 484 | 3152.447 > b01_mrg | REPEATED | 100 | avg |... Thank you, @vamsi-parasa ! I will investigate the result - PR Comment: https://git.openjdk.org/jdk/pull/13568#issuecomment-2068075025
Re: EnumeratedStream
I am not really familiar with goals and milestones of Valhalla project, but what I meant by simplification is that there would not be any more need to convert to promotove streams explicitly as Stream would be a thing. If that's what Valhalla is working on, then this would be just great. Performance concerns regarding wrappers are also valid , but here I am talking about implementation complexity. If going little off topic, compiling many classes to achieve generic reification in fact looks odd, but it in fact provides best developer experience, Converting primitive arrays to collections is one of the examples of major problems issues with it, along with some methods of Arrays class (like sort, if I am not mistaken), just don't work with primitives.Approach that is used in C#, while has its downsides, provides much better user experience. However, what I am looking into right now is some hybrid form of generic handling, where generic maybe be reified on demand of developer (or implicitly if primitive is used). I am working on some prototypes at the moment вс, 21 апр. 2024 г. в 16:31, - : > On Sun, Apr 21, 2024 at 5:49 AM ІП-24 Олександр Ротань < > rotan.olexa...@gmail.com> wrote: > >> I have heard your proposal. Your approach indeed for sure has its >> advantages. >> >> One thing I don't like referring to is Valhalla. It's not even a >> preview and no one really knows when it will be, relying on it when >> designing API now would be strange to say the least. >> > Valhalla's value classes are actually quite ready; the compatibility and > the type system are quite fleshed out in the recent iterations, and the > prototypes are already functional. > >> >> One possible thing that could dramatically simplify implementation of my >> approach is introduction of generic reification, which would allow >> primitives as type params. I am currently studying the working of javac and >> possible implementation of this is one of the topics in my research. >> However, let's stick to what we have in jdk right now from now on. >> > Generic reification is part of project Valhalla too, in that it allows > wrapper classes in generics to have the same performance as the primitives > with generic specialization. Compiling many classes to achieve generic > reification is an alternative, but I don't think it's feasible. > >> >> I would like to hear opinions of other people regarding the design of >> such API, especially David and Remi, since, as I understand, that's not the >> first time they witness a discussion like this, so maybe they have >> something to tell here. >> > Unfortunately you will have to wait. Most JDK engineers are employees who > work on weekdays; only a few are enthusiasts. I think we may get more > discussion traffic on Monday. >
Re: RFR: 8318650: Optimized subword gather for x86 targets. [v18]
> Hi All, > > This patch optimizes sub-word gather operation for x86 targets with AVX2 and > AVX512 features. > > Following is the summary of changes:- > > 1) Intrinsify sub-word gather using hybrid algorithm which initially > partially unrolls scalar loop to accumulates values from gather indices into > a quadword(64bit) slice followed by vector permutation to place the slice > into appropriate vector lanes, it prevents code bloating and generates > compact JIT sequence. This coupled with savings from expansive array > allocation in existing java implementation translates into significant > performance of 1.5-10x gains with included micro. > > ![image](https://github.com/openjdk/jdk/assets/59989778/e25ba4ad-6a61-42fa-9566-452f741a9c6d) > > > 2) Patch was also compared against modified java fallback implementation by > replacing temporary array allocation with zero initialized vector and a > scalar loops which inserts gathered values into vector. But, vector insert > operation in higher vector lanes is a three step process which first extracts > the upper vector 128 bit lane, updates it with gather subword value and then > inserts the lane back to its original position. This makes inserts into > higher order lanes costly w.r.t to proposed solution. In addition generated > JIT code for modified fallback implementation was very bulky. This may impact > in-lining decisions into caller contexts. > > Kindly review and share your feedback. > > Best Regards, > Jatin Jatin Bhateja has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 16 commits: - Merge branch 'master' of http://github.com/openjdk/jdk into JDK-8318650 - Review resolutions. - Review comment resolutions. - Review comments resolutions - Review comments resolutions. - Review comments resolutions. - Generalizing masked sub-gather support. - Merge branch 'master' of http://github.com/openjdk/jdk into JDK-8318650 - Merge branch 'master' of http://github.com/openjdk/jdk into JDK-8318650 - Fix incorrect comment - ... and 6 more: https://git.openjdk.org/jdk/compare/6d569961...b24cc5cd - Changes: https://git.openjdk.org/jdk/pull/16354/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=16354&range=17 Stats: 1178 lines in 32 files changed: 1129 ins; 21 del; 28 mod Patch: https://git.openjdk.org/jdk/pull/16354.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/16354/head:pull/16354 PR: https://git.openjdk.org/jdk/pull/16354
Re: EnumeratedStream
On Sun, Apr 21, 2024 at 5:49 AM ІП-24 Олександр Ротань < rotan.olexa...@gmail.com> wrote: > I have heard your proposal. Your approach indeed for sure has its > advantages. > > One thing I don't like referring to is Valhalla. It's not even a > preview and no one really knows when it will be, relying on it when > designing API now would be strange to say the least. > Valhalla's value classes are actually quite ready; the compatibility and the type system are quite fleshed out in the recent iterations, and the prototypes are already functional. > > One possible thing that could dramatically simplify implementation of my > approach is introduction of generic reification, which would allow > primitives as type params. I am currently studying the working of javac and > possible implementation of this is one of the topics in my research. > However, let's stick to what we have in jdk right now from now on. > Generic reification is part of project Valhalla too, in that it allows wrapper classes in generics to have the same performance as the primitives with generic specialization. Compiling many classes to achieve generic reification is an alternative, but I don't think it's feasible. > > I would like to hear opinions of other people regarding the design of such > API, especially David and Remi, since, as I understand, that's not the > first time they witness a discussion like this, so maybe they have > something to tell here. > Unfortunately you will have to wait. Most JDK engineers are employees who work on weekdays; only a few are enthusiasts. I think we may get more discussion traffic on Monday.
Re: EnumeratedStream
I have heard your proposal. Your approach indeed for sure has its advantages. One thing I don't like referring to is Valhalla. It's not even a preview and no one really knows when it will be, relying on it when designing API now would be strange to say the least. One possible thing that could dramatically simplify implementation of my approach is introduction of generic reification, which would allow primitives as type params. I am currently studying the working of javac and possible implementation of this is one of the topics in my research. However, let's stick to what we have in jdk right now from now on. I would like to hear opinions of other people regarding the design of such API, especially David and Remi, since, as I understand, that's not the first time they witness a discussion like this, so maybe they have something to tell here. вс, 21 апр. 2024 г. в 06:35, - : > On Sat, Apr 20, 2024 at 8:29 PM ІП-24 Олександр Ротань < > rotan.olexa...@gmail.com> wrote: > >> Gatherers could be effectively terminal, but I don't think Gatherer API >> designers intended it to be. In related JEP, gatherers are described as a >> way to declare custom intermediate operations, and introducing "terminal" >> gatherers would be misleading. >> > I will show you an API that expands on collectors too. > >> >> Talking about performance, not even considering gather() method itself, >> creating an instance of Indexed object for each value in stream is costy >> and might turn into a nightmare for infinite streams. >> > We will have value objects soon (Project Valhalla), by then the object > creation will be much more lightweight as it's effectively a tuple. This is > not really a thing of concern. > >> >> As for internals of Stream API right now, I am not aware about its >> current state, so not much to say here except that adding a new type of >> streams that just slightly extends existing functionality might not be that >> harmful, I guess. >> >> Regarding API exposure, I don't think that moving it from stream directly >> to Gatherers factory would be much of a deal since to see index-aware >> methods user must explicitly convert stream to enumerated. >> > Having another set of EnumeratedStream APIs and implementations is going > to be a nightmare to maintain. Also it has bad interpolatability to convert > itself back into regular streams for other usages, while Stream> > are much better in that aspect. > >> >> I also think the I didn't express my point about index consistency clear >> enough. Consider following: >> > Notice that Stream.filter retains instead of drops the matching elements! > Since otherwise your results don't make sense. I will assume you mean > "filter" like "dropIf" > >> >> List.of(1,2,3).stream().enumerated().filter((idx, i) -> i*idx < >> 2).map((idx, val) -> idx * val) >> >> Result : (4, 9) >> > Does idx start from 0 or 1? All Java indices start from 0, having it start > from 1 in enumerated is really weird. I will assume you mean [2, 6]=[1*2, > 2*3] > Your use case is even simpler, this case can be covered in a simple > gatherer like this: > Gatherer.ofSequential(() -> new int[] {0}, > Gatherer.Integrator.ofGreedy((counter, v, sink) -> > sink.push(new Indexed<>(counter[0]++, v > Better than writing thousands lines of new code. The functionalities are > already implemented in my sample project in > > https://github.com/liachmodded/IndexedStream/tree/main/src/main/java/com/github/liachmodded/indexedstream > >> >> With your approach >> >> List.of(1,2,3).stream().gather(Gatherers.filterIndexed((idx, val) -> >> idx*val < 2)).gather(Gatherers.mapIndexed((idx, val) -> idx * val)) >> >> Result : (2, 6) >> > I will assume you mean [0, 3]=[0*2, 1*3] > >> >> Not only second option is much more verbose, but also indexes of stream >> are inconsistent between operations. >> > Then what does EnumeratedStream serve? We would assume the enumeration > means the enumeration at the current stage so we want the number > immediately. If you want the enumeration at a particular stage, it's better > to zip your stream items with an index like my gatherer above at an > explicit step. > > Also I have already made a showcase git repository with your two test > cases at > > https://github.com/liachmodded/IndexedStream/blob/main/src/test/java/com/github/liachmodded/indexedstream/IndexedGatherersTest.java > Feel free to rant and tell what you really want that aren't served by > these few simple classes. > >> >> PS: regarding findIndex, I did some benchmarking today, you might like to >> take a look. On average list-based version outperform collector and >> gatherer-based in more then 10 times. And also lists in stdlib doesn't have >> any hashcode-based implementations. I wrote 19 implementations in list >> subclasses and none of them had anything but simple traversing logic inside >> indexOf. But that's topic of another thread >> > Thanks for the prompt, I will look at it and reply in the oth