...PureBasic 2x slower than Java?

Everything else that doesn't fall into one of the other PB categories.
Inertially
New User
New User
Posts: 9
Joined: Mon Nov 14, 2011 12:24 am

...PureBasic 2x slower than Java?

Post by Inertially »

Did Bubble Sort to sort a 50,000 int array.

Took twice as long with PureBasic...?
Image


Unless there's a mistake in the code (rather than just saying sorting is a dumb way to test speed).



PureBasic

Code: Select all

Procedure bubbleSort(Array arr.i(1))
  swapped.b = #True
  max.i = ArraySize(arr()) - 1
  
  While (swapped = #True)
    swapped = #False
    
    For i.i = 0 To max
      If arr(i) > arr(i + 1)
        temp.i = arr(i)
        arr(i) = arr(i + 1)
        arr(i + 1) =  temp
        
        swapped = #True
      EndIf
    Next i
    max = max - 1
  Wend
  
EndProcedure

OpenConsole()

size.l = 50000
PrintN("Bubble Sort Test..." + Str(size))

; Intialize array of random numbers
Dim bubs.i(size)
For i.i = 0 To size
  bubs(i) = Random(1000000)
Next

; Initial time
time.l = ElapsedMilliseconds()

; Sort using bubble sort
bubbleSort(bubs())

; Print time elapsed
PrintN("Time to Complete: " + Str(ElapsedMilliseconds() - time))

For i.i = 9000 To 9020
  PrintN(Str(bubs(i)))
Next i

Input()
CloseConsole()

Code: Select all

public class BubbleTest
{
    public static void main(String[] args)
    {
        final int size = 50000;

        System.out.println("Bubble Sort Test..." + size);
                
        int[] bubs = new int[size];
        for (int i = 0; i < size; i++)
            bubs[i] = (int) (Math.random() * 10000000);
        
        long time = System.currentTimeMillis();
        
        bubbleSort(bubs);
        
        System.out.println("Time to Complete: " + (System.currentTimeMillis() - time));
        
        for (int i = 2000; i < 2020; i++)
            System.out.println(bubs[i]);
    }
    
    public static void bubbleSort(int[] arr)
    {
        int len = arr.length;
        boolean swapped = true;
        
        while (swapped == true)
        {
            swapped = false;
            
            for (int i = 0; i < len - 1; i++)
            {
                if (arr[i] > arr[i + 1])
                {
                    int temp = arr[i];
                    arr[i] = arr[i + 1];
                    arr[i + 1] = temp;
                    
                    swapped = true;
                }
            }
            len--;
        }
    }
}
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: ...PureBasic 2x slower than Java?

Post by netmaestro »

My Purebasic run completed in 11450 vs. the 16021 you posted for the Java version. Did you disable the debugger to run the test?
BERESHEIT
Inertially
New User
New User
Posts: 9
Joined: Mon Nov 14, 2011 12:24 am

Re: ...PureBasic 2x slower than Java?

Post by Inertially »

16021 ms is PureBasic
8532 ms in Java on my computer.

The console window in the screenshot is the PB exe.
The Interactions pane in the Java IDE (lower) shows the time it took for Java.

Yeah, debugger is off, it's compiled..
and I tried it in C++, I got 14900 ms....
VB6 was 24000ms.

what's java doing that makes it faster..
User avatar
Arctic Fox
Enthusiast
Enthusiast
Posts: 609
Joined: Sun Dec 21, 2008 5:02 pm
Location: Aarhus, Denmark

Re: ...PureBasic 2x slower than Java?

Post by Arctic Fox »

@Inertially
I can confirm your result.

~7700 ms in PB 4.60 without debugger.
~4200 ms in Java 7.0.

I haven't got a clue why, though.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: ...PureBasic 2x slower than Java?

Post by netmaestro »

Uh-oh... at Ramihyn_'s suggestion (thanks!) I ran the Java version on my machine: 5340, or less than half Purebasic's time. No clue why unless Java is using register variables for math and PB isn't. Just an idea to throw out there. But there isn't any math in this really, so it's a stupid idea I guess.
Last edited by netmaestro on Mon Nov 14, 2011 2:04 am, edited 1 time in total.
BERESHEIT
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: ...PureBasic 2x slower than Java?

Post by IdeasVacuum »

Tested on PB4.51x86 WinXP 32bit SP3.

PB Bubble Sort Time to Complete: 14438ms

PB's SortArray() Time to Complete: 16ms

The results of the Tests are dependent on the test machine/platform of course, but clearly PB's own sort is competitive.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: ...PureBasic 2x slower than Java?

Post by netmaestro »

I made this change to the PB code and gained a second:

Code: Select all

       Swap arr(i), arr(i+1)
        ;temp.i = arr(i)
        ;arr(i) = arr(i + 1)
        ;arr(i + 1) =  temp
 
BERESHEIT
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: ...PureBasic 2x slower than Java?

Post by netmaestro »

IdeasVacuum wrote:but clearly PB's own sort is competitive.
No argument there, but almost anything's going to beat a bubble sort. Look at this as benchmark code to compare the speed/efficiency of the output of two compilers, where you must always compare apples to apples in the sorting routine used.
BERESHEIT
Inertially
New User
New User
Posts: 9
Joined: Mon Nov 14, 2011 12:24 am

Re: ...PureBasic 2x slower than Java?

Post by Inertially »

ehh
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: ...PureBasic 2x slower than Java?

Post by netmaestro »

Btw, 16ms sounds suspiciously like a Windows timeslice, where the actual time was probably much smaller. For SortArray(), I get 3ms with code adjusted for hi-res timing:

Code: Select all

ProcedureDLL.l TicksHQ() 
  Static maxfreq.q 
  Protected t.q 
  If maxfreq=0 
    QueryPerformanceFrequency_(@maxfreq) 
    maxfreq=maxfreq/1000
  EndIf 
  QueryPerformanceCounter_(@t) 
  ProcedureReturn t/maxfreq 
EndProcedure

OpenConsole()

size.l = 50000
PrintN("Bubble Sort Test..." + Str(size))

; Intialize array of random numbers
Dim bubs.i(size)
For i.i = 0 To size
  bubs(i) = Random(1000000)
Next

; Initial time
time.l = TicksHQ()

; Sort using bubble sort
SortArray(bubs(),#PB_Sort_Ascending)

; Print time elapsed
PrintN("Time to Complete: " + Str(TicksHQ() - time))

For i.i = 9000 To 9020
  PrintN(Str(bubs(i)))
Next i

Input()
CloseConsole()
BERESHEIT
User avatar
Arctic Fox
Enthusiast
Enthusiast
Posts: 609
Joined: Sun Dec 21, 2008 5:02 pm
Location: Aarhus, Denmark

Re: ...PureBasic 2x slower than Java?

Post by Arctic Fox »

I can reduce the original PB code by 600 ms when using a global array instead of passing it as a parameter. Should it be that much?
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: ...PureBasic 2x slower than Java?

Post by Demivec »

To create a more accurate comparison the unsorted arrays should be identical.

Here's a simple worst case setup using arrays sorted in reverse order:

Code: Select all

Dim bubs.i(Size)
For i.i = 0 To Size
  bubs(i) = Size - i
Next
The equivalent should be used in Java as well.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: ...PureBasic 2x slower than Java?

Post by IdeasVacuum »

To create a more accurate comparison the unsorted arrays should be identical
...good point!
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Shield
Addict
Addict
Posts: 1021
Joined: Fri Jan 21, 2011 8:25 am
Location: 'stralia!
Contact:

Re: ...PureBasic 2x slower than Java?

Post by Shield »

I tried to optimize the code a bit and came up with this
without using any explicit ASM instructions :) :

Code: Select all


Structure IntegerTuple
	first.i
	second.i
EndStructure

Procedure ShieldBubbleSort(Array buffer.i(1))
	Protected swapped.i = #True
	Protected length.i = ArraySize(buffer()) - 1
	Protected counter.i
	Protected *base
	Protected *entry.IntegerTuple
	
	*base = @buffer()
	While swapped = #True
		swapped = #False
		
		*entry = *base
		For counter = 0 To length
			If *entry\first > *entry\second
				Swap *entry\first, *entry\second
				swapped = #True
			EndIf
			*entry + SizeOf(Integer)
		Next
		length = length - 1
	Wend
	
	ProcedureReturn #True
EndProcedure
It's a little faster than the example provided by the OT (well, about three seconds on my system).
I viewed the assembler code PB outputs and noticed some flaws, like unnecessary copies,
i.e. copy value from stack into edx and then move it to eax or copying the same value twice from the stack into the same register.

I'm no ASM guru but with some simple modifications to the code and after using the /REASM switch
I managed to optimize it to run at twice the speed of the OT's code. But I'm sure there is even more potential. :)
Image
Blog: Why Does It Suck? (http://whydoesitsuck.com/)
"You can disagree with me as much as you want, but during this talk, by definition, anybody who disagrees is stupid and ugly."
- Linus Torvalds
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: ...PureBasic 2x slower than Java?

Post by Tenaja »

Shield wrote:...I viewed the assembler code PB outputs and noticed some flaws, like unnecessary copies,
i.e. copy value from stack into edx and then move it to eax or copying the same value twice from the stack into the same register.

I'm no ASM guru but with some simple modifications to the code and after using the /REASM switch
I managed to optimize it to run at twice the speed of the OT's code. But I'm sure there is even more potential. :)
This is the very reason I have requested improved output (optimization) rather than more features. I want something BETTER than java--that's why I chose a compiler rather than Java or C#.
Post Reply