Re: qsort, once again - Mailing list pgsql-hackers
From | Tom Lane |
---|---|
Subject | Re: qsort, once again |
Date | |
Msg-id | 23077.1142552202@sss.pgh.pa.us Whole thread Raw |
In response to | Re: qsort, once again ("Dann Corbit" <DCorbit@connx.com>) |
List | pgsql-hackers |
>> So at least on randomized data, the swap_cnt thing is a serious loser. >> Need to run some tests on special-case inputs though. Anyone have a >> test suite they like? > Here is a distribution maker that will create some torture tests for > sorting programs. I fleshed out the sort tester that Bentley & McIlroy give pseudocode for in their paper (attached below in case anyone wants to hack on it). Not very surprisingly, it shows the unmodified B&M algorithm as significantly better than the BSD-lite version: Our current BSD qsort: distribution SAWTOOTH: max cratio 12.9259, average 0.870261 over 252 tests distribution RAND: max cratio 1.07917, average 0.505924 over 252 tests distribution STAGGER: max cratio 12.9259, average 1.03706 over 252 tests distribution PLATEAU: max cratio 12.9259, average 0.632514 over 252 tests distribution SHUFFLE: max cratio 12.9259, average 1.21631 over 252 tests method COPY: max cratio 3.87533, average 0.666927 over 210 tests method REVERSE: max cratio 5.6248, average 0.710284 over 210 tests method FREVERSE: max cratio 12.9259, average 1.58323 over 210 tests method BREVERSE: max cratio 5.72661, average 1.13674 over 210 tests method SORT: max cratio 0.758625, average 0.350092 over 210 tests method DITHER: max cratio 3.13417, average 0.667222 over 210 tests Overall: average cratio 0.852415 over 1260 tests without the swap_cnt code: distribution SAWTOOTH: max cratio 5.6248, average 0.745818 over 252 tests distribution RAND: max cratio 1.07917, average 0.510097 over 252 tests distribution STAGGER: max cratio 5.6248, average 1.0494 over 252 tests distribution PLATEAU: max cratio 3.57655, average 0.411549 over 252 tests distribution SHUFFLE: max cratio 5.72661, average 1.05988 over 252 tests method COPY: max cratio 3.87533, average 0.712122 over 210 tests method REVERSE: max cratio 5.6248, average 0.751011 over 210 tests method FREVERSE: max cratio 4.80869, average 0.690224 over 210 tests method BREVERSE: max cratio 5.72661, average 1.13673 over 210 tests method SORT: max cratio 0.806618, average 0.539829 over 210 tests method DITHER: max cratio 3.13417, average 0.702174 over 210 tests Overall: average cratio 0.755348 over 1260 tests ("cratio" is the ratio of the actual number of comparison function calls to the theoretical expectation of N*lg2(N).) The insertion sort switchover is a loser for both average and worst-case measurements. I tried Dann's distributions too, with N = 100000: Our current BSD qsort: dist fib: cratio 0.0694229 dist camel: cratio 0.0903228 dist constant: cratio 0.0602126 dist five: cratio 0.132288 dist ramp: cratio 4.29937 dist random: cratio 1.09286 dist reverse: cratio 0.5663 dist sorted: cratio 0.18062 dist ten: cratio 0.174781 dist twenty: cratio 0.238098 dist two: cratio 0.090365 dist perverse: cratio 0.334503 dist trig: cratio 0.679846 Overall: max cratio 4.29937, average cratio 0.616076 over 13 tests without the swap_cnt code: dist fib: cratio 0.0694229 dist camel: cratio 0.0903228 dist constant: cratio 0.0602126 dist five: cratio 0.132288 dist ramp: cratio 4.29937 dist random: cratio 1.09286 dist reverse: cratio 0.89184 dist sorted: cratio 0.884907 dist ten: cratio 0.174781 dist twenty: cratio 0.238098 dist two: cratio 0.090365 dist perverse: cratio 0.334503 dist trig: cratio 0.679846 Overall: max cratio 4.29937, average cratio 0.695293 over 13 tests In this set of tests the behavior is just about identical, except for the case of already-sorted input, where the BSD coding runs in O(N) instead of O(N lg2 N) time. So that evidently is why some unknown person put in the special case. Some further experimentation destroys my original proposal to limit the size of subfile we'll use the swap_cnt code for: it turns out that that eliminates the BSD code's advantage for presorted input (at least for inputs bigger than the limit) without doing anything much in return. So my feeling is we should just remove the swap_cnt code and return to the original B&M algorithm. Being much faster than expected for presorted input doesn't justify being far slower than expected for other inputs, IMHO. In the context of Postgres I doubt that perfectly sorted input shows up very often anyway. Comments? regards, tom lane
Attachment
pgsql-hackers by date: