PB and VB.NET speed comparison

For everything that's not in any way related to PureBasic. General chat etc...
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Re: PB and VB.NET speed comparison

Post by Foz »

And as you should very well know, that is entirely database dependant.

With .net you have a choice of SQL Server direct or ODBC, whereas PB has Postgresql and SQLite direct or ODBC.

To make a "fair" comparison, you will have to choose a common ODBC connection, so the database is not relevent, and then you can do a comparison.

To be honest though, if all you want to do is string and variable comparisons, write out a csv file, read in a csv and do the calculations, diffs etc and make it count that way.
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: PB and VB.NET speed comparison

Post by ts-soft »

Olby wrote:For example create a new database, add a table, insert 1000 random records, save database, close it. Open database, read records, run some string comparisons/replacements, update data, close database. For me that would be a real-life scenario. :wink:
In real-life the database runs on a linux-server and you use it with a webinterface :mrgreen:
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
idle
Always Here
Always Here
Posts: 5840
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: PB and VB.NET speed comparison

Post by idle »

Olby wrote:Here's why: http://www.bobpowell.net/lockingbits.htm
In your .NET version you try to access every pixel "the slow way".
You mean the .Net way! :twisted:
If you want to compare speed you probably need to find a few basic examples to test different aspects
Perhaps a simple test of these Fibonacci procedures would be a good start.

Code: Select all

Procedure FibonacciRecursive(argx.i)
  If argx<=2
    ProcedureReturn 1
  Else  
   ProcedureReturn fibPB(argx-1)+fibPB(argx-2)
  EndIf
EndProcedure

Procedure Fibonacci(argx.i)
  Protected a,b,c
  If argx <= 2
    ProcedureReturn 1
  Else 
    a = 1
    b = 1
    While argx > 2
      c = a + b
      b = a
      a = c
      argx-1
    Wend
    ProcedureReturn c
 EndIf    
EndProcedure
Windows 11, Manjaro, Raspberry Pi OS
Image
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Re: PB and VB.NET speed comparison

Post by Foz »

That code is a tad odd!

Code: Select all

Procedure FibonacciRecursive(argx.i)
  If argx<=2
    ProcedureReturn 1
  Else  
   ProcedureReturn FibonacciRecursive(argx-1)+FibonacciRecursive(argx-2)
  EndIf
EndProcedure

Procedure Fibonacci(argx.i)
  Protected a,b,c
  If argx <= 2
    ProcedureReturn 1
  Else 
    a = 1
    b = 1
    While argx > 2
      c = a + b
      b = a
      a = c
      argx-1
    Wend
    ProcedureReturn c
 EndIf    
EndProcedure

t = ElapsedMilliseconds()
r1 = FibonacciRecursive(40)
t1 = ElapsedMilliseconds() - t
t = ElapsedMilliseconds()
r2 = Fibonacci(40)
t2 = ElapsedMilliseconds() - t


MessageRequester("", Str( t1 ) + "   " + Str( r1 ) + #CRLF$ + Str( t2 ) + "   " + Str( r2 ))
For the recursive on mine (t1 & r1) at 40, it takes 1800ms, whereas the non-recursive is a solid 0ms :?:
User avatar
idle
Always Here
Always Here
Posts: 5840
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: PB and VB.NET speed comparison

Post by idle »

you need to give it the beans
the recursive function aims to blow up the stack and should be slow
the non recursive version should be fast and shouldn't give the compiler much opportunity to optimize
and there shouldn't be much difference on execution time between compilers.
but you'd need to run the tests multiple times to get an average

Code: Select all

t = ElapsedMilliseconds()
r1 = FibonacciRecursive(40)
t1 = ElapsedMilliseconds() - t

t = ElapsedMilliseconds()
For a = 1 To 10000
r2 = Fibonacci(40)
Next
t2 = ElapsedMilliseconds() - t

MessageRequester("", Str( t1 ) + "   " + Str( r1 ) + #CRLF$ + StrF( t2/10000,6 ) + "   " + Str( r2 ))

Windows 11, Manjaro, Raspberry Pi OS
Image
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Re: PB and VB.NET speed comparison

Post by Foz »

Well, I ended up with another pure calculation test. PI, aiming to calculate 24M digits, but breaking after 10 seconds

here's a C# version:

Code: Select all

using System;

namespace RC__Pi
{
    internal sealed class Pi
    {
        private const int Scale = 10000;
        private const int ArrInit = 2000;

        private static void Main()
        {
            long digits = 24 * 1024 * 1024;
            long carry = 0;
            var arr = new long[digits + 1];

            for (long i = 0; i <= digits; ++i)
                arr[i] = ArrInit;

            int t = Environment.TickCount;

            for (long i = digits; i > 0; i -= 4)
            {
                long sum = 0;
                for (long j = i; j > 0; --j)
                {
                    sum = sum * j + Scale * arr[j];
                    arr[j] = sum % (j * 2 - 1);
                    sum /= j * 2 - 1;
                }
                Console.Write((carry + sum / Scale).ToString("D4"));
                carry = sum % Scale;

                if (Environment.TickCount - t > 10000)
                    break;
            }
            Console.WriteLine();
            Console.WriteLine("Break");
            Console.ReadLine();
        }
    }
}
and here is the PB version:

Code: Select all

#SCALE = 10000
#ARRINT=  2000
 
Procedure Pi(Digits)
  Protected First=#True, Text$
  Protected Carry, i, j, sum
  Dim Arr(Digits)
  For i=0 To Digits
    Arr(i)=#ARRINT
  Next
  
  t = ElapsedMilliseconds()
  i=Digits
  While i>0
    sum=0
    j=i
    While j>0
      sum * j + #SCALE * arr(j)
      Arr(j)=  sum % (j * 2 - 1)
      sum / (j * 2 - 1)
      j-1
    Wend
    Text$ = RSet(Str(Carry+sum/#SCALE),4,"0")
    If First
      Text$ = ReplaceString(Text$,"3","3.")
      First = #False
    EndIf
    Print(Text$)
    Carry=sum % #SCALE
    i - 4
    
    If ElapsedMilliseconds() - t > 10000
      Break
    EndIf
    
  Wend
EndProcedure
 
If OpenConsole()
  Pi(24 * 1024 * 1024)
  
  PrintN("")
  PrintN("Break")
  Input()
EndIf
End
Now remember boys and girls, that the executable code quality in PB is inferior, to an interpreted language, erm, I mean a JIT compiled language!

Here's the difference of output:
PB: 3.1415926535897932384626433832795028841971693993751058209
C#: 3141592653589793

:lol: I give up! :lol:
User avatar
Shield
Addict
Addict
Posts: 1021
Joined: Fri Jan 21, 2011 8:25 am
Location: 'stralia!
Contact:

Re: PB and VB.NET speed comparison

Post by Shield »

Just tested those routines out of curiosity (didn't care about the recursive one though).
The linear Fibonacci function was tested 100'000'000 times and the results are:

PB: 13791
.NET: 4290


Edit: Tested Java too...the result is as I expected...6 milliseconds. :wink:
Java is taking the entire loop out of the equation because it never changes,
so why bother even executing it? :wink:
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
KJ67
Enthusiast
Enthusiast
Posts: 218
Joined: Fri Jun 26, 2009 3:51 pm
Location: Westernmost tip of Norway

Re: PB and VB.NET speed comparison

Post by KJ67 »

Foz wrote:PB: 3.1415926535897932384626433832795028841971693993751058209
C#: 3141592653589793
Well, let's threw one more in there...
Here are my results;
C# with .Net 4.0:
314159265358979323846264
PB 4.61b4:
3.141592653589793238462643383279502884197169399375105820974944592307816406286
go1.0.1:
3141592653589793238462643383279528841971693993751058209749445923078164062862089986280348253

Code: Select all

// PiTest.go
package main

import (
	"fmt"
	"runtime"
	"time"
)

const (
	scale  = 10000
	arrint = 2000
)

func main() {
	fmt.Print(runtime.Version(), ": ")
	Pi(24 * 1024 * 1024)
	print("\nBreak\n")
}

func Pi(digits int) {
	var carry int
	arr := make([]int, digits+1)
	for i := 0; i < digits; i++ {
		arr[i] = arrint
	}
	done := time.After(1e10)
	for i := digits; i > 0; i -= 4 {
		select {
		case <-done:
			return
		default:
			sum := 0
			for j := i; j > 0; j-- {
				sum = (sum * j) + (scale * arr[j])
				arr[j] = sum % (j*2 - 1)
				sum /= j*2 - 1
			}
			fmt.Print((carry + sum/scale))
			carry = sum % scale
		}
	}
}
The best preparation for tomorrow is doing your best today.
Olby
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Jan 12, 2009 10:33 am
Contact:

Re: PB and VB.NET speed comparison

Post by Olby »

Here's my on Fibonacci:

Code: Select all

Procedure FibonacciRecursive(argx.i)
  If argx<=2
    ProcedureReturn 1
  Else 
   ProcedureReturn FibonacciRecursive(argx-1)+FibonacciRecursive(argx-2)
  EndIf
EndProcedure

Procedure Fibonacci(argx.i)
  Protected a,b,c
  If argx <= 2
    ProcedureReturn 1
  Else
    a = 1
    b = 1
    While argx > 2
      c = a + b
      b = a
      a = c
      argx-1
    Wend
    ProcedureReturn c
 EndIf   
EndProcedure

t = ElapsedMilliseconds()
r1 = FibonacciRecursive(40)
t1 = ElapsedMilliseconds() - t
t = ElapsedMilliseconds()
r2 = Fibonacci(40)
t2 = ElapsedMilliseconds() - t


MessageRequester("", Str( t1 ) + "   " + Str( r1 ) + #CRLF$ + Str( t2 ) + "   " + Str( r2 ))

Code: Select all

Module Module1

    Function FibonacciRecursive(ByVal argx As Integer) As Integer
        If argx <= 2 Then
            Return 1
        Else
            Return (FibonacciRecursive(argx - 1) + FibonacciRecursive(argx - 2))
        End If
    End Function

    Function Fibonacci(ByVal argx As Integer) As Integer
        Dim a, b, c As Integer
        If argx <= 2 Then
            Return 1
        Else
            a = 1
            b = 1
            While argx > 2
                c = a + b
                b = a
                a = c
                argx -= 1
            End While
            Return c
        End If
    End Function

    Sub Main()
        Dim t, r1, t1, r2, t2 As Integer

        t = Environment.TickCount
        r1 = FibonacciRecursive(40)
        t1 = Environment.TickCount - t
        t = Environment.TickCount
        r2 = Fibonacci(40)
        t2 = Environment.TickCount - t

        Console.WriteLine(t1 & "    " & r1 & vbCrLf & t2 & "    " & r2)
        Console.WriteLine("Press any key...")
        Console.ReadKey()
    End Sub

End Module
PB: 1701ms
NET: 1669ms
NET: 1420ms (without Integer Overflow Check)

Edit: Changed to ByVal as suggested by Danilo.
Last edited by Olby on Sun May 20, 2012 11:46 am, edited 2 times in total.
Intel Core i7 Quad 2.3 Ghz, 8GB RAM, GeForce GT 630M 2GB, Windows 10 (x64)
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: PB and VB.NET speed comparison

Post by Danilo »

Olby wrote:Here's my on Fibonacci:

PB: 1607ms
NET: 1841ms
Did you set your VB.NET project to release mode and run it without debugger?

My results:
PB: 1469
VB.NET: 1375
VB.NET: 1266 (ByVal)
VB.NET: 922 (ByVal and compiler option "/removeintchecks" (Disables integer overflow checking))


2nd VB.NET is with both ByRef changed to ByVal. ByVal is more correct IMO, you don't use a reference/pointer in PureBasic.
3rd VB.NET with disabled integer overflow checks.
Last edited by Danilo on Sun May 20, 2012 1:51 pm, edited 1 time in total.
User avatar
TI-994A
Addict
Addict
Posts: 2704
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: PB and VB.NET speed comparison

Post by TI-994A »

Olby wrote:That's the point we're not talking out some hardcore geek who wants to strip naked his Windows installation and be in charge of every byte CPU processes. We're talking about companies that will install .NET and run framework based software. I have worked with and for dozens different type of companies and majority run .NET based software and internally develop .NET software. Majority of regular computer users will have it installed no matter if they like it or not.
Yes, but these businesses and corporations usually have IT departments that employ such "hardcore geeks" who ensure that their systems are clean and lean. In any case, it is undeniable that dot net is widely used, but popularity is not superiority. Like you said, it’s a favoured tool for in-house development because of the time and effort it saves, but when commercially outsourced, IT personnel and consultants will invariably steer their organisations away from such developments, viewing them as less than professional.
Olby wrote:Application development time is far more important and more costly than deployment. You would spend more time with PB to do an app you could easily create using .NET. Explain that to your management when they want everything cheaper and faster. Let's put it that way. PB has it's roots in the old school days of software development, everything about it is old school. It doesn't mean it's incapable but in 21st century when time is money PB's advantage over .NET is arguable.
You’re right again, development time is crucial, but at what cost. As independent developers, cost and speed of development must go hand in hand with quality and performance, especially in this highly competitive field where every advantage matters. Furthermore, fiddling with framework downloads and installs is not only time consuming, but can also be a nightmare. In an ideal world where all systems have all the required framework versions and updates properly installed, and all the framework-dependent apps behave correctly, VB.Net may not be too bad. But unfortunately, that’s not the case. Install one version, and suddenly an existing app stops working; uninstall it in the wrong order, and suddenly an entire other version fails. Now imagine doing this across a corporate network, or even worse, imagine your product failing when someone else fiddles with the framework during some future installation. Product design and deployment should be clean and simple, and with PureBasic it can be as simple as copying one clean ready-to-run executable.

PureBasic may be low level, but far from old school. It smashes all the roadblocks we used to have with VB6, and it offers greater latitude of control as compared to VB.Net. PureBasic’s advantage over VB.Net is inarguably hands down.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: PB and VB.NET speed comparison

Post by Danilo »

Danilo wrote:
Olby wrote:Here's my on Fibonacci:

PB: 1607ms
NET: 1841ms
Did you set your VB.NET project to release mode and run it without debugger?

My results:
PB: 1469
VB.NET: 1375
VB.NET: 1266 (ByVal)

2nd VB.NET is with both ByRef changed to ByVal. ByVal is more correct IMO, you don't use a reference/pointer in PureBasic.
With compiler option "/removeintchecks" (Disables integer overflow checking):
VB.NET: 922
Olby
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Jan 12, 2009 10:33 am
Contact:

Re: PB and VB.NET speed comparison

Post by Olby »

TI-994A wrote:PureBasic’s advantage over VB.Net is inarguably hands down.
That's solely your opinion. As I said before there are situations where PB is great and situations where PB is frustrating to work with. Unfortunately it seems your experience dealing with framework is not a success and this is where all the prejudice comes from. If you could point me to an established company using PB on large scale developments I would be really surprised. You're right .net software might not be suitable for wide-spread commercial development and distribution but so is PureBasic. Developers will rather opt for professional environments and faster run-times (e.g. C++). Based on my personal experience I can definitely say that trying to sell software made in .NET (especially when source code needs to be provided) one will be more successful than trying to promote the same software written in PB. So when it boils down to most important aspect of software development - whether you can sell your developments, at the moment I would say it is .NET right after the established C/C++.
Danilo wrote:
My results:
PB: 1469
VB.NET: 1375
VB.NET: 1266 (ByVal)

2nd VB.NET is with both ByRef changed to ByVal. ByVal is more correct IMO, you don't use a reference/pointer in PureBasic.
Sweet results. I changed from ByRef to ByVal as you suggested and now .net is faster (see previous post) but with less of a margin than in your tests. Running Release executable.
Intel Core i7 Quad 2.3 Ghz, 8GB RAM, GeForce GT 630M 2GB, Windows 10 (x64)
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: PB and VB.NET speed comparison

Post by Danilo »

Olby wrote:Sweet results. I changed from ByRef to ByVal as you suggested and now .net is faster (see previous post) but with less of a margin than in your tests. Running Release executable.
I should say that compiler option "/optimize" was enabled here by default in VS2010 SP1 VB.NET console project.
Optimizations and "/removeintchecks" (Disables integer overflow checking) disabled makes VB.NET slower than PB.
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: PB and VB.NET speed comparison

Post by Danilo »

Foz wrote:Well, I ended up with another pure calculation test. PI, aiming to calculate 24M digits, but breaking after 10 seconds

here's a C# version:

Code: Select all

using System;

namespace RC__Pi
{
    internal sealed class Pi
    {
        private const int Scale = 10000;
        private const int ArrInit = 2000;

        private static void Main()
        {
            long digits = 24 * 1024 * 1024;
            long carry = 0;
            var arr = new long[digits + 1];

            for (long i = 0; i <= digits; ++i)
                arr[i] = ArrInit;

            int t = Environment.TickCount;

            for (long i = digits; i > 0; i -= 4)
            {
                long sum = 0;
                for (long j = i; j > 0; --j)
                {
                    sum = sum * j + Scale * arr[j];
                    arr[j] = sum % (j * 2 - 1);
                    sum /= j * 2 - 1;
                }
                Console.Write((carry + sum / Scale).ToString("D4"));
                carry = sum % Scale;

                if (Environment.TickCount - t > 10000)
                    break;
            }
            Console.WriteLine();
            Console.WriteLine("Break");
            Console.ReadLine();
        }
    }
}
and here is the PB version:

Code: Select all

#SCALE = 10000
#ARRINT=  2000
 
Procedure Pi(Digits)
  Protected First=#True, Text$
  Protected Carry, i, j, sum
  Dim Arr(Digits)
  For i=0 To Digits
    Arr(i)=#ARRINT
  Next
  
  t = ElapsedMilliseconds()
  i=Digits
  While i>0
    sum=0
    j=i
    While j>0
      sum * j + #SCALE * arr(j)
      Arr(j)=  sum % (j * 2 - 1)
      sum / (j * 2 - 1)
      j-1
    Wend
    Text$ = RSet(Str(Carry+sum/#SCALE),4,"0")
    If First
      Text$ = ReplaceString(Text$,"3","3.")
      First = #False
    EndIf
    Print(Text$)
    Carry=sum % #SCALE
    i - 4
    
    If ElapsedMilliseconds() - t > 10000
      Break
    EndIf
    
  Wend
EndProcedure
 
If OpenConsole()
  Pi(24 * 1024 * 1024)
  
  PrintN("")
  PrintN("Break")
  Input()
EndIf
End
Now remember boys and girls, that the executable code quality in PB is inferior, to an interpreted language, erm, I mean a JIT compiled language!

Here's the difference of output:
PB: 3.1415926535897932384626433832795028841971693993751058209
C#: 3141592653589793

:lol: I give up! :lol:
Nice trick, Foz! :D

I removed the check in PB for adding the point, it is more fair.

My results:

Code: Select all

PB: 31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253
C#: 31415926535897932384626433832795
Your trick is to mix 32bit and 64bit values in C# (int = 32bit, long = 64bit). If you convert all long to int,
the result is:

Code: Select all

PB: 31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253
C#: 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093
Of course release version and disabled debuggers.

Code: Select all

using System;

namespace RC__Pi
{
    internal sealed class Pi
    {
        private const int Scale = 10000;
        private const int ArrInit = 2000;

        private static void Main()
        {
            int digits = 24 * 1024 * 1024;
            int carry = 0;
            var arr = new int[digits + 1];

            for (int i = 0; i <= digits; ++i)
                arr[i] = ArrInit;

            int t = Environment.TickCount;

            for (int i = digits; i > 0; i -= 4)
            {
                int sum = 0;
                for (int j = i; j > 0; --j)
                {
                    sum = sum * j + Scale * arr[j];
                    arr[j] = sum % (j * 2 - 1);
                    sum /= j * 2 - 1;
                }
                Console.Write((carry + sum / Scale).ToString("D4"));
                carry = sum % Scale;

                if (Environment.TickCount - t > 10000)
                    break;
            }
            Console.WriteLine();
            Console.WriteLine("Break");
            Console.ReadLine();
        }
    }
}
PB version:

Code: Select all

#SCALE = 10000
#ARRINT=  2000
 
Procedure Pi(Digits)
  Protected First=#True, Text$
  Protected Carry, i, j, sum
  Dim Arr(Digits)
  For i=0 To Digits
    Arr(i)=#ARRINT
  Next
  
  t = ElapsedMilliseconds()
  i=Digits
  While i>0
    sum=0
    j=i
    While j>0
      sum * j + #SCALE * arr(j)
      Arr(j)=  sum % (j * 2 - 1)
      sum / (j * 2 - 1)
      j-1
    Wend
    ;Text$ = RSet(Str(Carry+sum/#SCALE),4,"0")
    ;If First
    ;  Text$ = ReplaceString(Text$,"3","3.")
    ;  First = #False
    ;EndIf
    Print(RSet(Str(Carry+sum/#SCALE),4,"0"))
    Carry=sum % #SCALE
    i - 4
    
    If ElapsedMilliseconds() - t > 10000
      Break
    EndIf
    
  Wend
EndProcedure
 
If OpenConsole()
  Pi(24 * 1024 * 1024)
  
  PrintN("")
  PrintN("Break")
  Input()
EndIf
End
Post Reply