Skip to content

JDK-8266431: Dual-Pivot Quicksort improvements (Radix sort) #3938

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

iaroslavski
Copy link
Contributor

@iaroslavski iaroslavski commented May 8, 2021

Sorting:

  • adopt radix sort for sequential and parallel sorts on int/long/float/double arrays (almost random and length > 6K)
  • fix tryMergeRuns() to better handle case when the last run is a single element
  • minor javadoc and comment changes

Testing:

  • add new data inputs in tests for sorting
  • add min/max/infinity values to float/double testing
  • add tests for radix sort

Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Error

 ⚠️ OCA signatory status must be verified

Integration blocker

 ⚠️ Whitespace errors (failed with the updated jcheck configuration)

Issue

  • JDK-8266431: Dual-Pivot Quicksort improvements (Radix sort) (Enhancement - P4)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/3938/head:pull/3938
$ git checkout pull/3938

Update a local copy of the PR:
$ git checkout pull/3938
$ git pull https://git.openjdk.org/jdk.git pull/3938/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 3938

View PR using the GUI difftool:
$ git pr show -t 3938

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/3938.diff

Webrev

Link to Webrev Comment

Sorting:

- adopt radix sort for sequential and parallel sorts on int/long/float/double arrays (almost random and length > 6K)
- fix tryMergeRuns() to better handle case when the last run is a single element
- minor javadoc and comment changes

Testing:
- add new data inputs in tests for sorting
- add min/max/infinity values to float/double testing
- add tests for radix sort
@bourgesl
Copy link
Contributor

bourgesl commented May 9, 2021

Congratulation,
what an amazing job !

DPQS is now 50% faster in average but 2.5 times faster (rms) my favorite !!

Finally OOME is now handled to let sort work under low-mem conditions !

I will work on more benchmarks for long/float/double types.

Laurent

@bridgekeeper bridgekeeper bot added the oca Needs verification of OCA signatory status label May 10, 2021
@bridgekeeper
Copy link

bridgekeeper bot commented May 10, 2021

Hi @iaroslavski, welcome to this OpenJDK project and thanks for contributing!

We do not recognize you as Contributor and need to ensure you have signed the Oracle Contributor Agreement (OCA). If you have not signed the OCA, please follow the instructions. Please fill in your GitHub username in the "Username" field of the application. Once you have signed the OCA, please let us know by writing /signed in a comment in this pull request.

If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please use "Add GitHub user iaroslavski" as summary for the issue.

If you are contributing this work on behalf of your employer and your employer has signed the OCA, please let us know by writing /covered in a comment in this pull request.

@openjdk
Copy link

openjdk bot commented May 10, 2021

@iaroslavski The following label will be automatically applied to this pull request:

  • core-libs

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@iaroslavski
Copy link
Contributor Author

/signed

@bridgekeeper bridgekeeper bot added the oca-verify Needs verification of OCA signatory status label May 10, 2021
@bridgekeeper
Copy link

bridgekeeper bot commented May 10, 2021

Thank you! Please allow for up to two weeks to process your OCA, although it is usually done within one to two business days. Also, please note that pull requests that are pending an OCA check will not usually be evaluated, so your patience is appreciated!

int[] count4 = new int[256];

for (int i = low; i < high; ++i) {
count1[ a[i] & 0xFF]--;
Copy link

@jhorstmann jhorstmann May 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a reviewer, but having recently implemented a radixsort myself I'm wondering what is the logic or benefit of decrementing and counting backwards here?

One thing I did differently, and I'm not fully sure is an optimization, is remembering the last bucket for each of the 4 counts. Checking whether the data is already sorted by that digit can then be done by checking count[last_bucket] == size, which avoids the first loop in passLevel. Again, not sure whether it is actually faster, maybe the two separate simple loops like here are better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jhorstmann In counting backwards we perform comparing with 0 in a loop, Comparing with 0 may be faster than comparing with other value. In general, backward or forward moving is your favor.

Keeping last_bucket and use check count[last_bucket] == size sounds good, but we need to run benchmarking and compare. I think we will not see big difference because the size of count array is too small, 256 only, whereas we scan whole array with size at least 6K. The corner case when we can see max effect of using last_bucket is array with all equal elements (4 count arrays will have only one non-zero element). but such array will be caught by tryMerge method.

*
* @author Vladimir Yaroslavskiy
* @author Jon Bentley
* @author Josh Bloch
* @author Doug Lea
*
* @version 2018.08.18
* @version 2020.06.14
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vladimir, I would update to 2021.05.06 (+your hash)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Laurent, the date in this class is not the date of our last commit,
this date is the date when I have final idea regarding to Radix sort,
therefore, I prefer to keep 2020.06.14

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as you want, but you should maybe indicate which version corresponds to your master code too.

It would help tracking changes between forks (iarosalvskiy/sorting master)

Copy link
Contributor

@richardstartin richardstartin May 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @iaroslavski I'm unconvinced that this work was from 14/06/2020 - I believe this work derives from an unsigned radix sort I implemented on 10/04/2021 richardstartin/radix-sort-benchmark@ab4da23#diff-6c13d3fb74f38906677dbfa1a70a123c8e5baf4a39219c81ef121e078d0013bcR226 which has numerous structural similarities to this work:

  • Producing all four histograms in one pass
  • Skipping passes based on detecting the total in the histogram
  • Bailing out of the skip detection if a nonzero value not equal to the total is encountered
  • Manually unrolling the LSD radix sort loop in order to avoid array copies

My implementation from 10th April is below for reference:

  public static void unrollOnePassHistogramsSkipLevels(int[] data) {
    int[] histogram1 = new int[257];
    int[] histogram2 = new int[257];
    int[] histogram3 = new int[257];
    int[] histogram4 = new int[257];

    for (int value : data) {
      ++histogram1[(value & 0xFF) + 1];
      ++histogram2[((value >>> 8) & 0xFF) + 1];
      ++histogram3[((value >>> 16) & 0xFF) + 1];
      ++histogram4[(value >>> 24) + 1];
    }
    boolean skipLevel1 = canSkipLevel(histogram1, data.length);
    boolean skipLevel2 = canSkipLevel(histogram2, data.length);
    boolean skipLevel3 = canSkipLevel(histogram3, data.length);
    boolean skipLevel4 = canSkipLevel(histogram4, data.length);

    if (skipLevel1 && skipLevel2 && skipLevel3 && skipLevel4) {
      return;
    }
    int[] copy = new int[data.length];

    int[] source = data;
    int[] dest = copy;

    if (!skipLevel1) {
      for (int i = 1; i < histogram1.length; ++i) {
        histogram1[i] += histogram1[i - 1];
      }
      for (int value : source) {
        dest[histogram1[value & 0xFF]++] = value;
      }
      if (!skipLevel2 || !skipLevel3 || !skipLevel4) {
        int[] tmp = dest;
        dest = source;
        source = tmp;
      }
    }

    if (!skipLevel2) {
      for (int i = 1; i < histogram2.length; ++i) {
        histogram2[i] += histogram2[i - 1];
      }
      for (int value : source) {
        dest[histogram2[(value >>> 8) & 0xFF]++] = value;
      }
      if (!skipLevel3 || !skipLevel4) {
        int[] tmp = dest;
        dest = source;
        source = tmp;
      }
    }

    if (!skipLevel3) {
      for (int i = 1; i < histogram3.length; ++i) {
        histogram3[i] += histogram3[i - 1];
      }
      for (int value : data) {
        dest[histogram3[(value >>> 16) & 0xFF]++] = value;
      }
      if (!skipLevel4) {
        int[] tmp = dest;
        dest = source;
        source = tmp;
      }
    }

    if (!skipLevel4) {
      for (int i = 1; i < histogram4.length; ++i) {
        histogram4[i] += histogram4[i - 1];
      }
      for (int value : source) {
        dest[histogram4[value >>> 24]++] = value;
      }
    }
    if (dest != data) {
      System.arraycopy(dest, 0, data, 0, data.length);
    }
  }

  private static boolean canSkipLevel(int[] histogram, int dataSize) {
    for (int count : histogram) {
      if (count == dataSize) {
        return true;
      } else if (count > 0) {
        return false;
      }
    }
    return true;
  }

Moreover, @bourgesl forked my repository on 11/04/2021 and communicated with me about doing so. On 25/04/2021 there was a new implementation of DualPivotQuicksort with a signed radix sort but the same structural similarities, and with the same method and variable names in places bourgesl/radix-sort-benchmark@90ff7e4#diff-397ce8fd791e2ce508cf9127201bc9ab46264cd2a79fd0487a63569f2e4b59b2R607-R609

    // TODO add javadoc
    private static void radixSort(Sorter sorter, int[] a, int low, int high) {
        int[] b;
        // LBO: prealloc (high - low) +1 element:
        if (sorter == null || (b = sorter.b) == null || b.length < (high - low)) {
            // System.out.println("alloc b: " + (high - low));
            b = new int[high - low];
        }

        int[] count1, count2, count3, count4;
        if (sorter != null) {
            sorter.resetRadixBuffers();
            count1 = sorter.count1;
            count2 = sorter.count2;
            count3 = sorter.count3;
            count4 = sorter.count4;
        } else {
            // System.out.println("alloc radix buffers(4x256)");
            count1 = new int[256];
            count2 = new int[256];
            count3 = new int[256];
            count4 = new int[256];
        }

        for (int i = low; i < high; ++i) {
            --count1[ a[i]         & 0xFF ];
            --count2[(a[i] >>>  8) & 0xFF ];
            --count3[(a[i] >>> 16) & 0xFF ];
            --count4[(a[i] >>> 24) ^ 0x80 ];
        }

        boolean skipLevel4 = canSkipLevel(count4, low - high);
        boolean skipLevel3 = skipLevel4 && canSkipLevel(count3, low - high);
        boolean skipLevel2 = skipLevel3 && canSkipLevel(count2, low - high);

        count1[255] += high;
        count2[255] += high;
        count3[255] += high;
        count4[255] += high;

        // 1 todo process LSD
        for (int i = 255; i > 0; --i) {
            count1[i - 1] += count1[i];
        }

        for (int i = low; i < high; ++i) {
            b[count1[a[i] & 0xFF]++ - low] = a[i];
        }

        if (skipLevel2) {
            System.arraycopy(b, 0, a, low, high - low);
            return;
        }

        // 2
        for (int i = 255; i > 0; --i) {
            count2[i - 1] += count2[i];
        }

        //for (int value : b) {
        //    a[count2[(value >> 8) & 0xFF]++] = value;
        for (int i = low; i < high; ++i) {
            a[count2[(b[i] >> 8) & 0xFF]++] = b[i];
        }

        if (skipLevel3) {
            return;
        }

        // 3
        for (int i = 255; i > 0; --i) {
            count3[i - 1] += count3[i];
        }

        for (int i = low; i < high; ++i) {
            b[count3[(a[i] >> 16) & 0xFF]++ - low] = a[i];
        }

        if (skipLevel4) {
            System.arraycopy(b, 0, a, low, high - low);
            return;
        }

        // 4
        for (int i = 255; i > 0; --i) {
            count4[i - 1] += count4[i];
        }

        // for (int value : b) {
        //    a[count4[ (value >>> 24) ^ 0x80]++] = value;
        for (int i = low; i < high; ++i) {
            a[count4[ (b[i] >>> 24) ^ 0x80]++] = b[i];
        }
    }

    // TODO: add javadoc
    private static boolean canSkipLevel(int[] count, int total) {
        for (int c : count) {
            if (c == 0) {
                continue;
            }
            return c == total;
        }
        return true;
    }

Later, the name of the method canSkipLevel changed to skipByte: bourgesl/radix-sort-benchmark@a693b26#diff-397ce8fd791e2ce508cf9127201bc9ab46264cd2a79fd0487a63569f2e4b59b2R719 - this is the name of the method in the version of this sort you committed on 05/01/2021 richardstartin/sorting@f076073#diff-4b4d68fc834c2ad12a9fb9d316a812221af7c398338ed2ee907d0a795e7aadafR601-R604

    // TODO add javadoc
//  private 
    static void radixSort(Sorter sorter, int[] a, int low, int high) {
//System.out.println("                        Radix !!!");
        int[] count1 = new int[256];
        int[] count2 = new int[256];
        int[] count3 = new int[256];
        int[] count4 = new int[256];

        for (int i = low; i < high; ++i) {
            count1[ a[i]         & 0xFF ]--;
            count2[(a[i] >>>  8) & 0xFF ]--;
            count3[(a[i] >>> 16) & 0xFF ]--;
            count4[(a[i] >>> 24) ^ 0x80 ]--;
        }
        boolean skipByte4 = skipByte(count4, low - high, high, true);
        boolean skipByte3 = skipByte(count3, low - high, high, skipByte4);
        boolean skipByte2 = skipByte(count2, low - high, high, skipByte3);
        boolean skipByte1 = skipByte(count1, low - high, high, skipByte2);

        if (skipByte1) {
//Main.check(a, low, high - 1); // todo
            return;
        }
//        int xorA = Main.getXor(a, low, high);

        int[] b; int offset = low;

        if (sorter == null || (b = (int[]) sorter.b) == null) {
            b = new int[high - low];
        } else {
            offset = sorter.offset;
//System.out.println("      !!!! offset: " + offset);
        }
        int start = low - offset;
        int last = high - offset;


        // 1 todo process LSD
        for (int i = low; i < high; ++i) {
            b[count1[a[i] & 0xFF]++ - offset] = a[i];
        }

//        if (xorA != Main.getXor(a, low, high)) System.out.println("6K_4 1 xor changed");

        if (skipByte2) {
            System.arraycopy(b, start, a, low, high - low);
//Main.check(a, low, high - 1); // todo
            return;
        }

        // 2
        for (int i = start; i < last; ++i) {
            a[count2[(b[i] >> 8) & 0xFF]++] = b[i];
        }

//        if (xorA != Main.getXor(a, low, high)) System.out.println("6K_4 2 xor changed");

        if (skipByte3) {
//Main.check(a, low, high - 1); // todo
            return;
        }

        // 3
        for (int i = low; i < high; ++i) {
            b[count3[(a[i] >> 16) & 0xFF]++ - offset] = a[i];
        }

//        if (xorA != Main.getXor(a, low, high)) System.out.println("6K_4 3 xor changed");

        if (skipByte4) {
            System.arraycopy(b, start, a, low, high - low);
//Main.check(a, low, high - 1); // todo
            return;
        }

//        if (xorA != Main.getXor(a, low, high)) System.out.println("6K_4 4 xor changed");
        // 4
        for (int i = start; i < last; ++i) {
            a[count4[(b[i] >>> 24) ^ 0x80]++] = b[i];
        }
//        if (xorA != Main.getXor(a, low, high)) System.out.println("6K_4 5 xor changed");
//Main.check(a, low, high - 1); // todo
    }

    // TODO: add javadoc
    private static boolean skipByte(int[] count, int total, int high, boolean prevSkip) {
        if (prevSkip) {
            for (int c : count) {
                if (c == 0) {
                    continue;
                }
                if (c == total) {
                    return true;
                }
                break;
            }
        }
        // todo create historgam
        count[255] += high;

        for (int i = 255; i > 0; --i) {
            count[i - 1] += count[i];
        }
        return false;
    }

skipByte was later renamed to passLevel here, which is the name used in this PR: richardstartin/sorting@22357e4#diff-4b4d68fc834c2ad12a9fb9d316a812221af7c398338ed2ee907d0a795e7aadaf

Given the structural similarities mentioned, the chronological order of these commits, and the demonstrable provenance of the method name passLevel from canSkipLevel and since you have patented sort algorithms in the past, I want to make sure that it is recognised that this work is derived from my own.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You misunderstood my approach:

  • vladimir & tagir discussed radix sorts since previous work on DPQS in 2019
  • I enjoyed reading your blog post testing the performance of your radix sort vs Arrays.sort()
  • I tested and forked your radix-sort-benchmark to reproduce your experiments on openjdk16 (dpqs 19.11)
  • Vladimir proposed his own radixsort()
  • I did port DPQS impls in my fork of your benchmark to make a global comparison: dpqs 11, 19, 21 vs yours + arrays.sort(): it helped comparing implementations and decide when radix sort wins depending on dataset presortness
  • I tried many variants on my github repositories, but Vladimir never merged any of my change as he is not a regular github user (clone, fork, merge).

Our goal is not to underestimate your work (sort + benchmark) but Vladimir wrote his own code, me many experiments (tests, benchmarks) to obtain this original patch, written by Vladimir, with his radix sort implementation working on any int/long/float/double arrays, following the GPLv2 license.

You gave me motivation to make Arrays.sort() faster and we worked hard to write, test and benchmark this patch to be ready for OpenJDK 17

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @iaroslavski I'm unconvinced that this work was from 14/06/2020 - I believe this work derives from an unsigned radix sort I implemented on 10/04/2021 richardstartin/radix-sort-benchmark@ab4da23#diff-6c13d3fb74f38906677dbfa1a70a123c8e5baf4a39219c81ef121e078d0013bcR226 which has numerous structural similarities to this work:
Moreover, @bourgesl forked my repository on 11/04/2021 and communicated with me about doing so. On 25/04/2021 there was a new implementation of DualPivotQuicksort with a signed radix sort but the same structural similarities, and with the same method and variable names in places bourgesl/radix-sort-benchmark@90ff7e4#diff-397ce8fd791e2ce508cf9127201bc9ab46264cd2a79fd0487a63569f2e4b59b2R607-R609

@iaroslavski The attribution is not clear here. Can you provide a summary as to who is contributing to this patch? I can't tell if all involved have signed the OCA or not. I'm sure there will be questions about space/time trade-offs with radix sort but I think it's important to first establish the origins of this patch first.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AlanBateman There was discussion with Richard Startin, where Laurent and I explained the origin of my patch. There was misunderstanding based on git changes only. Finally Richard wrote comment in PR on May 13, 2021,
I duplicate it here:

"In private correspondence with Vladimir, it was explained that where Vladimir's code and Laurent's code are identical, including typos (Vladimir's code, Laurent's code) it is because Vladimir sent the code to Laurent, not the other way around, therefore Vladimir's code does not derive from Laurent's, and it does not derive from mine. I can only trust that this is the case, so please disregard my claim that this is derivative work when reviewing this PR."

@AlanBateman Vertical pipeline of PR hides comments in the middle and you have to click on "Show more..." to see all comments. There are no claims related to the origin of my patch, it doesn't violate any rights.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AlanBateman Vertical pipeline of PR hides comments in the middle and you have to click on "Show more..." to see all comments. There are no claims related to the origin of my patch, it doesn't violate any rights.

There is a comment from richardstartin suggesting that something was derived from code in his repo. Is this a benchmark that is not part of this PR? Only asking because I can't find him on OCA signatories. You can use the Skara /contributor command to list the contributors.

Copy link
Contributor Author

@iaroslavski iaroslavski Sep 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mentioned benchmarking is not a part of this PR. Our benchmarking was done by Laurent.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AlanBateman my claim was that the implementation was derived from my implementation, and demonstrated a sequence of name changes after @bourgesl forked my repository containing a structurally similar radix sort implementation and benchmarks, in order to provide circumstantial evidence for my claim. Via email @iaroslavski told me that this was not the case, which I decided to accept at face value. So please judge this PR on its merits, and disregard the claims made in these comments. I have not signed an OCA but do not want to block this PR if the space time tradeoff is deemed acceptable.

*/
if (a[e1] < a[e2] && a[e2] < a[e3] && a[e3] < a[e4] && a[e4] < a[e5]) {

/*
* Invoke radix sort on large array.
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer testing (sorter == null) first as it is always true for sequential sort and avoid testing bits > ... in this case

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense, I will update.

count1[ a[i] & 0xFF]--;
count2[(a[i] >>> 8) & 0xFF]--;
count3[(a[i] >>> 16) & 0xFF]--;
count4[(a[i] >>> 24) ^ 0x80]--;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that C2 can't eliminate the bounds check here because of the xor, even though this can't possibly exceed 256. The three masked accesses above are all eliminated. Maybe someone could look in to improving that.

Copy link

@neliasso neliasso May 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @neliasso, thanks for making a comment in an OpenJDK project!

All comments and discussions in the OpenJDK Community must be made available under the OpenJDK Terms of Use. If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please Use "Add GitHub user neliasso for the summary.

If you are not an OpenJDK Author, Committer or Reviewer, simply check the box below to accept the OpenJDK Terms of Use for your comments.

Your comment will be automatically restored once you have accepted the OpenJDK Terms of Use.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with Laurent (bourgesl), see his comment on May 15 regarding to xor:
using Unsafe is only 2% faster, not worth the extra complexity for few percent.

Copy link

@neliasso neliasso May 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @neliasso, thanks for making a comment in an OpenJDK project!

All comments and discussions in the OpenJDK Community must be made available under the OpenJDK Terms of Use. If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please Use "Add GitHub user neliasso for the summary.

If you are not an OpenJDK Author, Committer or Reviewer, simply check the box below to accept the OpenJDK Terms of Use for your comments.

Your comment will be automatically restored once you have accepted the OpenJDK Terms of Use.

Copy link

@neliasso neliasso May 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @neliasso, thanks for making a comment in an OpenJDK project!

All comments and discussions in the OpenJDK Community must be made available under the OpenJDK Terms of Use. If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please Use "Add GitHub user neliasso for the summary.

If you are not an OpenJDK Author, Committer or Reviewer, simply check the box below to accept the OpenJDK Terms of Use for your comments.

Your comment will be automatically restored once you have accepted the OpenJDK Terms of Use.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing hotspot C2 (xor) so quickly !

Sorting:

- move radix sort out from quicksort partitioning
- rename radixSort to tryRadixSort
- minor javadoc and comment changes

Testing:
- rename radixSort to tryRadixSort in helper
Testing:
- remove @SInCE and @Date, otherwise jtreg tag parser fails
@bridgekeeper
Copy link

bridgekeeper bot commented Jun 26, 2021

@iaroslavski This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@iaroslavski
Copy link
Contributor Author

Still waiting OCA approval

@bourgesl
Copy link
Contributor

Still waiting for individual OCA approval

@iaroslavski
Copy link
Contributor Author

iaroslavski commented Jul 26, 2021 via email

@bridgekeeper
Copy link

bridgekeeper bot commented Aug 23, 2021

@iaroslavski This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@iaroslavski
Copy link
Contributor Author

Still waiting OCA approval

@bridgekeeper bridgekeeper bot removed oca Needs verification of OCA signatory status oca-verify Needs verification of OCA signatory status labels Sep 13, 2021
@openjdk openjdk bot added the rfr Pull request is ready for review label Sep 13, 2021
@mlbridge
Copy link

mlbridge bot commented Sep 13, 2021

* Optimized mixed insertion sort
* Optimized insertion sort
* Optimized Radix sort
* Updated microbenchmark
@bourgesl
Copy link
Contributor

bourgesl commented Nov 20, 2022

@bridgekeeper
Copy link

bridgekeeper bot commented Dec 18, 2022

@iaroslavski This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@iaroslavski
Copy link
Contributor Author

This PR will be moved to the new one.

@bridgekeeper
Copy link

bridgekeeper bot commented Jan 16, 2023

@iaroslavski This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@iaroslavski
Copy link
Contributor Author

This PR is being moved to the new PR.

@bridgekeeper
Copy link

bridgekeeper bot commented Feb 14, 2023

@iaroslavski This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@bourgesl
Copy link
Contributor

I am currently preparing my PR against latest jdk to start an official review...

@bridgekeeper
Copy link

bridgekeeper bot commented Apr 10, 2023

@iaroslavski This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@iaroslavski
Copy link
Contributor Author

Laurent is finishing benchmarking.

@bridgekeeper
Copy link

bridgekeeper bot commented May 9, 2023

@iaroslavski This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@iaroslavski
Copy link
Contributor Author

Keeping this PR for a while

@bridgekeeper
Copy link

bridgekeeper bot commented Jun 6, 2023

@iaroslavski This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@iaroslavski
Copy link
Contributor Author

Keeping alive

@bridgekeeper
Copy link

bridgekeeper bot commented Jul 6, 2023

@iaroslavski This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@iaroslavski
Copy link
Contributor Author

Keeping alive

@bridgekeeper
Copy link

bridgekeeper bot commented Aug 10, 2023

@iaroslavski This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@iaroslavski
Copy link
Contributor Author

Keeping alive for a while

@bridgekeeper
Copy link

bridgekeeper bot commented Sep 10, 2023

@iaroslavski This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@iaroslavski
Copy link
Contributor Author

next version is under developing

@openjdk
Copy link

openjdk bot commented Sep 21, 2023

@iaroslavski this pull request can not be integrated into master due to one or more merge conflicts. To resolve these merge conflicts and update this pull request you can run the following commands in the local repository for your personal fork:

git checkout JDK-8266431-Dual-Pivot-Quicksort-improvements-Radix-sort
git fetch https://git.openjdk.org/jdk.git master
git merge FETCH_HEAD
# resolve conflicts and follow the instructions given by git merge
git commit -m "Merge master"
git push

@openjdk openjdk bot added the merge-conflict Pull request has merge conflict with target branch label Sep 21, 2023
@bridgekeeper
Copy link

bridgekeeper bot commented Oct 20, 2023

@iaroslavski This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@iaroslavski
Copy link
Contributor Author

will resolve merge conflicts

@bridgekeeper
Copy link

bridgekeeper bot commented Dec 5, 2023

@iaroslavski This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@bridgekeeper
Copy link

bridgekeeper bot commented Jan 2, 2024

@iaroslavski This pull request has been inactive for more than 8 weeks and will now be automatically closed. If you would like to continue working on this pull request in the future, feel free to reopen it! This can be done using the /open pull request command.

@bridgekeeper bridgekeeper bot closed this Jan 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core-libs [email protected] merge-conflict Pull request has merge conflict with target branch oca Needs verification of OCA signatory status
Development

Successfully merging this pull request may close these issues.