Integrated: 8329331: Intrinsify Unsafe::setMemory

2024-04-21 Thread Scott Gibbons
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]

2024-04-21 Thread Jatin Bhateja
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.

2024-04-21 Thread Jatin Bhateja
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]

2024-04-21 Thread Scott Gibbons
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]

2024-04-21 Thread Vladimir Kozlov
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

2024-04-21 Thread ІП-24 Олександр Ротань
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]

2024-04-21 Thread Vladimir Yaroslavskiy
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

2024-04-21 Thread ІП-24 Олександр Ротань
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]

2024-04-21 Thread Jatin Bhateja
> 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

2024-04-21 Thread -
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

2024-04-21 Thread ІП-24 Олександр Ротань
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