Important alert: (current site time 7/16/2013 2:51:59 AM EDT)
 

winzip icon

Sort without sorting (one million elements in 3(!) seconds) Update

Email
Submitted on: 8/13/2004 11:31:17 AM
By: ULLI 
Level: Advanced
User Rating: By 35 Users
Compatibility: VB 6.0
Views: 20077
author picture
(About the author)
 
     This Sort-Class can be used to retrieve the elements in a one-dimensional table of strings in either ascending or descending sequence. The table itself is not altered in any way by this process, rather pointers into the table are returned which point to the elements in the table in the requested order. Tests on a 1800 MHz Athlon processor have shown that the Sort is in fact the fastest I know, sorting 100,000 elements on a five byte random sort key in under 0.3 seconds. The speed varies only very slightly with the number of elements to be sorted, so one million elements take about three seconds to sort. Any special presorting has no measurable effect on speed (Quicksort by contrast is almost killed by a presorted sequence).

 
winzip iconDownload code

Note: Due to the size or complexity of this submission, the author has submitted it as a .zip file to shorten your download time. Afterdownloading it, you will need a program like Winzip to decompress it.Virus note:All files are scanned once-a-day by Planet Source Code for viruses, but new viruses come out every day, so no prevention program can catch 100% of them. For your own safety, please:
  1. Re-scan downloaded files using your personal virus checker before using it.
  2. NEVER, EVER run compiled files (.exe's, .ocx's, .dll's etc.)--only run source code.
  3. Scan the source code with Minnow's Project Scanner

If you don't have a virus scanner, you can get one at many places on the net including:McAfee.com

 
Terms of Agreement:   
By using this code, you agree to the following terms...   
  1. You may use this code in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
  2. You MAY NOT redistribute this code (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.   
  3. You may link to this code from another website, but ONLY if it is not wrapped in a frame. 
  4. You will abide by any additional copyright restrictions which the author may have placed in the code or code's description.


Other 111 submission(s) by this author

 


Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this code (in the Advanced category)?
(The code with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments

8/13/2004 11:40:47 AMFady1956

Although Roger fixed Evan's sort routines, Ulli is still the best. Thanks all for sharing ! :)
(If this comment was disrespectful, please report it.)

 
8/13/2004 12:04:29 PMPhantom Man

Hi Ulli

Small Type Error in Your Form_Load Sub

KeySize Should Be : UsedKeySize

Brilliant code.

Regards
Gary
(If this comment was disrespectful, please report it.)

 
8/13/2004 12:11:40 PMEvan Toder

look what i started here 00000 for ulli
(If this comment was disrespectful, please report it.)

 
8/13/2004 12:43:43 PMUlli

Phantom Man: this is what happens with last minute alterations ;-)
(If this comment was disrespectful, please report it.)

 
8/13/2004 1:06:10 PMVesa Piittinen

Umm, the items in the array are still in the exact same order? It is like the code does nothing. I made it output the array to two listboxes (with 10000 items), one with the array items before and one after. Are the sort results stored some other way?
(If this comment was disrespectful, please report it.)

 
8/13/2004 1:14:46 PMGandolf_The_GUI

My 1,000,000 Items took 10.1 seconds. Excellent speed for a million items!!!
(If this comment was disrespectful, please report it.)

 
8/13/2004 1:34:50 PMUlli

No Vesa, they are not. Why should they? You get them one by on in sorted order and it is up to you what you do with them.
(If this comment was disrespectful, please report it.)

 
8/13/2004 1:37:17 PMUlli

Gandolf: Did you compile it? Because that's roughliy the speed when the code is interpreted in the IDE.
(If this comment was disrespectful, please report it.)

 
8/13/2004 1:41:30 PMUlli

Vesa again: put some code in the NextPointer Event to fill the second listbox, like:

lb.Add UnsortedTable(Pointer)
(If this comment was disrespectful, please report it.)

 
8/13/2004 2:35:25 PMGandolf_The_GUI

No.. that was IDE speed, which is still darn impressive, I think.
(If this comment was disrespectful, please report it.)

 
8/13/2004 2:48:44 PMTom Pydeski

Ulli,
You're a genius!

(If this comment was disrespectful, please report it.)

 
8/13/2004 5:10:10 PMEd Porter

This code is excellent! On a 280MHz Win95 machine it takes 8.2 seconds to sort 100,000 items in the IDE and 4.1 seconds to sort 100,000 items as an .exe.

This is amazing performance for a legacy system.

Thanks for sharing! 5 Stars!

Sincerely,
Ed Porter
(If this comment was disrespectful, please report it.)

 
8/13/2004 10:06:11 PMThushan Fernando

Hi Ulli, although it comes as no suprise you've done an excellent job yet again. 5 globes for the code and an added 5 globes for taking the time to write up some documentation for it:-)
(If this comment was disrespectful, please report it.)

 
8/14/2004 2:30:01 AMKnoton

100000 elements sorted in 0,4994375 seconds with 63386 distinct keys :-) thank you Ulli, this goes into my codecollection for sure :-)
(If this comment was disrespectful, please report it.)

 
8/14/2004 3:37:39 AM

The code is, as usual, magnificent, but most users (such as Vesa) will want an array of pointers for subsequent processing of the sorted list. This can be done by adding the lines:
Ptr(Nxt)=Pointer
Nxt=Nxt+1
in Ulli's Sort_NextPointer routine, with the Ptr array and Nxt suitably initialised. But I think most folk would prefer the Class to include this pointer array so they didn't have to mess around during the sort. It's easy for a user to add, but it might be nice if Ulli could include it in an official minor upgrade to this wonderful code.
Steve

(If this comment was disrespectful, please report it.)

 
8/14/2004 3:52:07 AMUlli

Steve: what's the difference between subsequent processing of the pointers (one by one) once they are in an array of pointers - and processing the pointers as the come (one by one)?
(If this comment was disrespectful, please report it.)

 
8/14/2004 4:52:00 AMGB

On a 3ghz it took only .8295313 seconds - in the IDE :o
(If this comment was disrespectful, please report it.)

 
8/14/2004 9:26:00 AMNorm Cook

One small tweak: In my tests, AscB is about twice as fast as Asc. With code as written, 1.54675 for Asc, 1.468 for AscB
Again, great code.

(If this comment was disrespectful, please report it.)

 
8/14/2004 9:40:21 AM

Ulli,
Often I want to interact with the sorted data in an intelligent way. For example, I might become interested in the 59th element then might want to see what the 58th and 60th are. If I find out that I'm interested in the 59th element without having a permanent pointer to the 58th then I will have no way of doing this. Hence my need for a permanent pointer array rather than processing things on the fly.
Hope this helps

Steve

(If this comment was disrespectful, please report it.)

 
8/14/2004 10:31:12 AMUlli

Steve: Yes, I understand, but then again it's easy to build that array of pointers yourself. Why build it by default (causing additional overhead) if it is not needed in the majority of cases?
(If this comment was disrespectful, please report it.)

 
8/14/2004 10:46:53 AMUlli

Norm: Thanks for the tip. Does in fact improve timing by about 10%...
(If this comment was disrespectful, please report it.)

 
8/14/2004 2:06:14 PMVesa Piittinen

But how about sorting "unicode" strings? AscB probably doesn't work for those. So what if somebody wants to sort Japanese or Arabian for example?
(If this comment was disrespectful, please report it.)

 
8/14/2004 3:39:49 PMUlli

Vesa: VB I S unicode
(If this comment was disrespectful, please report it.)

 
8/14/2004 4:36:42 PMBenjamin Turski

Awesome.. 1 million in 9.78 seconds in IDE with a P4 2.54GHz.
(If this comment was disrespectful, please report it.)

 
8/14/2004 10:01:38 PMPaul Turcksin

his code is great and most PSC'ers will agree. But nobody mentioned the documentation, which is superb. In brief : creative thinking, nice code and proper documentation makes this submission excellent for learning and on top a usefull and ready-to-use tool. Heaven on earth.
(If this comment was disrespectful, please report it.)

 
8/16/2004 2:00:26 PMjames kahl

Very Impressive!!! I agree with Paul totally, great documentation, many people can and hopefully will learn alot about the way software development should be done from this excellent submission.
(If this comment was disrespectful, please report it.)

 
8/17/2004 7:20:16 AMShafeek mohammed

When I run this code I am getting the following results

00000453
00000572
00000042
00000787
00000989
00001973

42 is appearing after two greater numbers, Can someone explain this ?

(If this comment was disrespectful, please report it.)

 
8/17/2004 10:13:52 AMUlli

What's the original unsorted sequence of the numbers? And what's the length of your sort key?

Ooops? *smile*
(If this comment was disrespectful, please report it.)

 
8/18/2004 10:14:56 AMShafeek mohammed

My problem stated above was changed when I changed UsedKeySize to 8
(If this comment was disrespectful, please report it.)

 
9/13/2004 1:07:03 PMCharles Kincaid

I have been looking for a fast sort routine for my Pocket PC applications. Now all I have to do is convert this code to VB .net
(If this comment was disrespectful, please report it.)

 
12/23/2004 3:19:53 PMPhishbowla

Looks like fabulous code. Like Vesa said above, I don't understand where the output is. But I am not an advanced programmer. I searched for NextPointerEvent which is located in the cSort class file, but not sure where you would add a listbox line of code to demonstrate it in real time. Could anyone explain to me the changes necessary for it to be seen in action?

phishbowlah@hotmail.com
(If this comment was disrespectful, please report it.)

 
12/26/2004 7:30:22 PM

If I put a breakpoint at Erase Anchor, Chain 'Release Memory, (program as from zip file by the way) should I be able to see the sort order in chain(x), with chain(x) holding the pointer value back into the table? Chain(x) doesn't appear to do this on my testing in either asc or desc! Where is it held in sorted order?
(If this comment was disrespectful, please report it.)

 
10/12/2005 1:27:45 PMRobin Orheden

Isent radixsort faster? If not then its a hell of a sort you got there!
(If this comment was disrespectful, please report it.)

 
11/21/2005 12:49:20 PMUlli

Robin, this IS a kind of radix sort, only that it starts at the MSD rather than the LSD
(If this comment was disrespectful, please report it.)

 
12/31/2005 10:19:40 PMRde

Hi Ulli.

I'm realy blown away by this algo.
Very fast and stable!

It's a bit complex to fully understand from a quick look but as you noted above I guessed this was a type of radix sort on strings!

Just one small hickup - can it be converted to handle case-insensative sorting (if asc 97 to 102 asc = asc - 32?).

Most impressive still *****.

Happy coding,
Rd :)
(If this comment was disrespectful, please report it.)

 
1/1/2006 10:41:26 AMRde

I guess you know I meant 122 (not 102):

If asc >= 97 or asc <= 122 then
asc = asc - 32
End if

etc....
(If this comment was disrespectful, please report it.)

 
1/7/2006 12:23:27 PMUlli

@Rde

Use the Alphabet property or the KeyTranslation property
(If this comment was disrespectful, please report it.)

 
1/8/2006 3:06:34 AMRde

Thanks for the tip Ulli:


Case-insensative (Caps first):

cSort.Alphabet = " !" & Chr(34) & "#$%&'()*+,-./0123456789:;<=>?@AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"

Case-insensative
(Lower first):

cSort.Alphabet = " !" & Chr(34) & "#$%&'()*+,-./0123456789:;<=>?@aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ"
(If this comment was disrespectful, please report it.)

 
1/8/2006 3:19:40 AMRde

Sorry, my bad:

Case-insensative (Caps first):

cSort.Alphabet = " !" & Chr(34) & "#$%&'()*+,-./0123456789:;<=>?@[\]^_`AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZ z"

Case-insensative
(Lower first):

cSort.Alphabet = " !" & Chr(34) & "#$%&'()*+,-./0123456789:;<=>?@[\]^_`aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYz Z"
(If this comment was disrespectful, please report it.)

 
8/5/2006 5:27:53 PMAchmad Junus

I'm not really understand about execution flow on this program and how its work. Perhaps by writing my own code, I can understand.
Once i put these syntax right before button click procedure ends:

Set cSort = Nothing
End Sub

Everything is destroyed!!

This is a program for indexing array of string. Not a real sorting program, that's what I think.
Anyway, is there an option to make this index become permanent and automatically updated when an array modified? :)


(If this comment was disrespectful, please report it.)

 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular code, please click here instead.)
 

To post feedback, first please login.