Hi, >From performance point of view, it does not matter whether we use >Float.isNaN(ak) or (ak != ak). Hotspot generates the same native code.
As for not skipping trailing nans, can you explain why it could be faster? Thank you, Dmytro Sheyko > Date: Tue, 8 Jun 2010 18:09:42 +0400 > From: iaroslav...@mail.ru > Subject: Re: New portion of improvements for Dual-Pivot Quicksort > To: dmytro_she...@hotmail.com > CC: core-libs-dev@openjdk.java.net > > Hello, > > Good catch! I agree with k!=p condition, but have doubt about using > Float.isNaN(ak) instead of ak != ak in for loop. Float.isNaN does exactly > the same comparison and at the same time it is called for all elements > of the array. > > I checked now and see that it is better to eliminate while loop, > and the best case is: > > for (int k = right; k >= left; k--) { > float ak = a[k]; > if (ak != ak) { // a[k] is NaN > a[k] = a[right]; > a[right--] = ak; > } > } > > If we have a lot of NaNs, it will be proceeded on linear time > and only small amount of elements will be sorted. If there are > no NaNs [at the end] - more probably use case - this code works > faster. I run simple test and it shows that case without while loop > is little bit faster, ~0.5%. > > Please, see attached version. > > Thank you, > Vladimir > > Dmytro Sheyko wrote: > > Hi, > > > > Coming back to NaN processing. > > It appeared that current code unnecessarily stirs up NaNs in the end of > > array even when they are just on their places. > > So I propose to replace these code > > /* > > * Phase 1: Move NaNs to the end of the array. > > */ > > for (int k = left; k <= right; k++) { > > float ak = a[k]; > > if (ak != ak) { // a[k] is NaN > > a[k--] = a[right]; > > a[right--] = ak; > > } > > } > > with following > > /* > > * Phase 1: Move NaNs to the end of the array. > > */ > > while (left <= right && Float.isNaN(a[right])) { > > right--; > > } > > for (int k = right - 1; k >= left; k--) { > > float ak = a[k]; > > if (Float.isNaN(ak)) { > > a[k] = a[right]; > > a[right] = ak; > > right--; > > } > > } > > > > Also I would like to note that while we are processing negative zeros, > > condition (k != p) is unnecessary. > > > > for (int k = left + 1, p = left; k <= right; k++) { > > float ak = a[k]; > > if (ak != 0.0f) { > > return; > > } > > if (Float.floatToRawIntBits(ak) < 0) { // ak is -0.0f > > if (k != p) { // !!! always true > > a[k] = +0.0f; > > a[p] = -0.0f; > > } > > p++; > > } > > } > > > > Here k is strictly greater than p initially and then grows faster than p. > > > > > > > From: iaroslav...@mail.ru > > > To: dmytro_she...@hotmail.com > > > CC: core-libs-dev@openjdk.java.net; iaroslav...@mail.ru > > > Subject: Re[4]: New portion of improvements for Dual-Pivot Quicksort > > > Date: Sat, 5 Jun 2010 23:40:31 +0400 > > > > > > I tried with separate method sortPivotCandidates(...), no changes in > > behaviour, > > > but at the same time I don't see that the method makes sources much > > cleaner, > > > inline comments are enough. I attach the latest version of DPQ. > > > > > > Fri, 4 Jun 2010 14:21:58 +0700 письмо от Dmytro Sheyko > > <dmytro_she...@hotmail.com>: > > > > > > > Seems good, > > > > > > > > One note. Since we gave up to sort pivot candidates in local > > variables, maybe we can move this out to separate procedure (in order to > > make sources cleaner a bit), e.g. > > > > > > > > private static void sortPivotCandidates(double[] a, int ae1, int > > ae2, int ae3, int ae4, int ae5) > > > > > > > > Hope the compiler is able to inline it without extra cost. > > > > > > > > Thanks, > > > > Dmytro Sheyko > > > > > > > > > From: iaroslav...@mail.ru > > > > > To: dmytro_she...@hotmail.com > > > > > CC: core-libs-dev@openjdk.java.net; iaroslav...@mail.ru > > > > > Subject: Re[2]: New portion of improvements for Dual-Pivot Quicksort > > > > > Date: Fri, 4 Jun 2010 01:17:57 +0400 > > > > > > > > > > Hello, > > > > > > > > > > I tried your case (which is selection sort) and it works as > > expected: not worse > > > > > than "network" or "bubble" sorting. But nevertheless, the best > > choice is to use > > > > > insertion sort, I wrote more elegant implementation, see: > > > > > > > > > > ///int ae1 = a[e1], ae3 = a[e3], ae5 = a[e5], ae2 = a[e2], ae4 = > > a[e4]; > > > > > > > > > > // Sort these elements using insertion sort > > > > > if (a[e2] < a[e1]) { int t = a[e2]; a[e2] = a[e1]; a[e1] = t; } > > > > > > > > > > if (a[e3] < a[e2]) { int t = a[e3]; a[e3] = a[e2]; a[e2] = t; > > > > > if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } > > > > > } > > > > > if (a[e4] < a[e3]) { int t = a[e4]; a[e4] = a[e3]; a[e3] = t; > > > > > if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; > > > > > if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } > > > > > } > > > > > } > > > > > if (a[e5] < a[e4]) { int t = a[e5]; a[e5] = a[e4]; a[e4] = t; > > > > > if (t < a[e3]) { a[e4] = a[e3]; a[e3] = t; > > > > > if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; > > > > > if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } > > > > > } > > > > > } > > > > > } > > > > > > > > > > ///a[e1] = ae1; a[e3] = ae3; a[e5] = ae5; a[e2] = ae2; a[e4] = ae4; > > > > > > > > > > Note that this implementation doesn't use local variables ae1, .. > > , ae5 > > > > > at all, and without variables it works faster. This code is not > > too long, > > > > > extra 4 lines only. And if on client VM it works as other "network" > > > > > implementations, but on server VM it wins 1.2%. > > > > > > > > > > In compare with first implementation of Dual-Pivot Quicksort, which > > > > > is used now in JDK 7, suggested version wins ~15% and 6% for client > > > > > and server modes. > > > > > > > > > > Updated version of the class I will send tomorrow. > > > > > > > > > > Dmytro, > > > > > could you please look at suggested insertion sort for 5 elements? > > > > > > > > > > Do you have any comments/improvements? One place to be improved > > > > > is last two ifs "if (a[e4] < ..." and "if (a[e5] < ..." where > > > > > element is compared with all sorted elements, whereas we can save > > > > > comparisons by binary fork. But implementation becomes too complex > > > > > and long. > > > > > > > > > > As it can be expected, the best sorting for small arrays is > > insertion, > > > > > then selection and then only bubble sort, even for 5 elements. > > > > > > > > > > Best regards, > > > > > Vladimir _________________________________________________________________ Hotmail: Free, trusted and rich email service. https://signup.live.com/signup.aspx?id=60969