Seite 1 von 7

Geschwindigkeit

Verfasst: 20.11.2012 10:59
von lite
Hallo

Beschäftige mich seit einigen Monaten mit PureBasic. Die Grundidee, einem Basic-Syntax in Assembler umzuwandeln finde ich genial. Deshalb hab ich mich entschlossen, diese Programmiersprache zu kaufen.
Nach den ersten Anfangsschwierigkeiten läuft es sehr gut mit den ersten Programmen.
Was mir aufgefallen ist, PureBasic ist viel zu langsam.
Gleiche operationen in einer anderen Sprache wie z.B. Autoit sind wesentlich schneller.
Nach meiner Messung teilweise um die 20-30%.
Jetzt wird Autoit nicht umgewandelt, sondern nur das Script in die .Exe gepackt, ist das schon verwunderlich.
Das enttäuscht schon sehr. Jetzt möcht ich nicht gleich Aufgeben, weil die Idee von PureBasic super ist.

In meinen Prg verarbeite ich 1 Arrayfeld und Strings, zwischendurch werden noch Dateien kopiert.

Jetzt meine Frage, Was kann man beachten, damit das Prg schneller wird ?

Grüße

Lite

Re: Geschwindigkeit

Verfasst: 20.11.2012 11:05
von c4s
War der Debugger an? Hast du schlecht (d.h. der Performance schadend) programmiert? Hat eventuell ein Antiviren-Tool PureBasic blockiert?
Poste mal deinen Code, den du zum Vergleichen verwendet hast...

Re: Geschwindigkeit

Verfasst: 20.11.2012 11:13
von STARGÅTE
Bild
Warte c4s, ich sehe ich gleich ^^

Re: Geschwindigkeit

Verfasst: 20.11.2012 15:50
von DrShrek
Vieleicht hat lite aber einfach nur recht.

Re: Geschwindigkeit

Verfasst: 20.11.2012 16:00
von NicTheQuick
Ein Programm ist immer so schnell wie man es programmiert. Man kann auch in ASM, C oder C++ arschlangsame Programme schreiben.
Vermutlich kennst du noch nicht alle Feinheiten von Purebasic und schimpfst unbegründet darüber. Deshalb wäre ein Beispielcode von dir hilfreich, der uns zeigt, wie du das Problem gelöst hast.

Re: Geschwindigkeit

Verfasst: 20.11.2012 16:49
von ts-soft
DrShrek hat geschrieben:Vieleicht hat lite aber einfach nur recht.
Du solltest aber abschecken können, das PB ca. 10 - 20x schneller als AutoIt ist und das Problem
woanders liegt.

Re: Geschwindigkeit

Verfasst: 20.11.2012 17:07
von lite
Hallo

Zuvor ein paar Infos. Ja, der Debugger ist aus.
Es ist ein Programm, das viele Textdateien liest (ca. 200 Stück) mit ca 400-1000 Lines pro Datei.
Jede Datei wird zeilenweise gelesen, bis die Section erreicht wurde.
Ab den Zeilpunkt werden die Zeilen analysiert und weiterverarbeit.

Das Programm muss Ansi und Unicode unterstützen.Den ganzen Quellcode zu posten wäre ein wenig umfangreich.
Sind mom. 4500 Lines.

Hier ein Auszug:

Purebasic:

Code: Alles auswählen


Procedure.s StringStrip(str$)
  ; stringstripleft (unicode)
  res$=""
  For x =0 To Len(str$)*2 Step 2
    uni=PeekU(@str$+x)
    If uni>32
      res$=Mid(str$,1+(x/2))
      Break
    EndIf
  Next
  ; stringstripright (unicode)
  str$=""
  res$= ReverseString(res$)
  For x =0 To Len(res$)*2 Step 2
    uni=PeekU(@res$+x)
    If uni>32
      str$=Mid(res$,1+(x/2))
      Break
    EndIf   
  Next
  str$= ReverseString(str$)
  ProcedureReturn str$
EndProcedure

Procedure _readsection(File$,Section$)
  
  Section$=LCase(Section$)
  File = OpenFile(1, File$)
  If File
    Format.l = ReadStringFormat(1)
    If Format = #PB_Ascii Or Format = #PB_UTF8 Or Format = #PB_Unicode
      length = Lof(1)
      If length
       *mem= AllocateMemory(length)
       ReadData(1, *mem, length)
      
       TxtFile$=PeekS(*mem,length,Format)
       FreeMemory(*mem) 
       CloseFile(1)
            
       Sectfound=0
       lins$=""      
       For x=1 To CountString(TxtFile$,#LF$)+1
        lin$= StringField(TxtFile$,x,#LF$)
        Line$ = StringStrip(lin$)  ; " " und #tab entfernen

        If Left(Line$, 1) = "["
         If Sectfound=1: Break: EndIf
         Sectfound=0
        EndIf
      
        If Sectfound=1
         If Line$="": Continue: EndIf ; leere Zeile
         If Left(Line$,2) = "//": Continue: EndIf
			   If Left(Line$,2) = "##": Continue: EndIf
			  			  
			   If Right(Line$,2)=",\"
				  lins$+RTrim(Line$,"\")
				  Continue
			   EndIf
			   lins$+Line$
		
			  
 			   Debug(lins$)
			   lins$=""
			  EndIf
        If LCase(Line$) = "["+Section$+"]": Sectfound=1: EndIf
       Next
      EndIf
    EndIf
  EndIf
EndProcedure
Autoit

Code: Alles auswählen

Func _readsection($sFileName,$sSection)
	local $x

	$sLine = StringSplit(FileRead($sFileName), @LF)
	$sfound_sect =0
	$slins=""	; temp var für line
	for $x=1 to $sLine[0]
		$sLine[$x]= StringStripWS($sLine[$x],3)
		if $sLine[$x]="" then ContinueLoop ; leere Zeile
		if stringleft($sline[$x],1)= "["  then $sfound_sect =0; vielleicht andere liste ? lesen stoppen
		if $sfound_sect=1 then
			
			$sLine[$x]= StringStripWS($sLine[$x],3)
			if stringleft($sLine[$x],2) = "//" then ContinueLoop
			if stringleft($sLine[$x],2) = "##" then ContinueLoop

			if StringRight($sLine[$x],2)=",\" then
				$sLine[$x]=StringTrimRight($sLine[$x],1)
				$slins=$slins&$sLine[$x]
				ContinueLoop
			endif
			$slins=$slins&$sLine[$x]

			consolewrite($slins&crlf)
			$slins=""
			
		endif
		if $sline[$x] ="["&$sSection&"]" then $sfound_sect=1
	next
endfunc
Wie gesagt, wen ich das Programm in beiden Sprachen starte, ist Autoit 30 % schneller.

Bitte bei der Diskussion sachlich bleiben.

Grüße
Lite

Re: Geschwindigkeit

Verfasst: 20.11.2012 17:28
von STARGÅTE
  • Es ist sehr schlecht, in der For-To-Schleife als End-Bedingung die Funktion CountString(TxtFile$,#LF$) zu nutzen. Der Grund ist der, dass dieser Befehl relativ langsam ist und mit jedem schleifendurchgang erneut ausgeführt wird.
    Besser wäre es hier sowas zu verwenden, da du ja die Variable x nicht brauchst:

    Code: Alles auswählen

    For x=CountString(TxtFile$,#LF$) To 0 Step -1
    So wird dieser Befehl nur einmal ausgeführt.
  • Deine Funktion StringStrip() ist natürlich überhaupt nicht optimiert, das dehen von Strings ist langsam und unnötig.
    Auch dort wieder sind Funktionen in der Schleife, die den Code verlangsammen. Hier wäre es bedeutend einfacher, den String als Pointer zu übergeben und dann in einem Unicode-Array nach betreffenden Zeichen zu suchen und am ende einen gekürzten String zurückzugeben.
Edit: Hier mal meine StringStrip() Variante:

Code: Alles auswählen

Structure CharacterArray
	c.c[0]
EndStructure

Procedure.s StringStrip(*Char.CharacterArray)
	Protected Length.i = MemoryStringLength(*Char)-1
	Protected Index.i = 0
	While *Char\c[Index] <= 32
		Index + 1
	Wend
	While *Char\c[Length] <= 32
		Length - 1
	Wend
	ProcedureReturn PeekS(@*Char\c[Index], Length-Index+1)
EndProcedure


Define String.s = #TAB$+#TAB$+"  Tabs und Leerzeichen"+#TAB$+"  "
MessageRequester("","'"+String+"'"+#LF$+"'"+StringStrip(@String)+"'")

Re: Geschwindigkeit

Verfasst: 21.11.2012 08:08
von DrShrek
Jetzt noch die AutoIt Sourcen optimieren und dann geht "das Rennen" weiter.

Aktuell steht es 1:0 für AutoIt (weil kostenlos)

Re: Geschwindigkeit

Verfasst: 21.11.2012 10:52
von lite
Hallo

Danke Stargate für die Info.
Deine Vorschläge sind interessant. Hab das gestern getestet. Die Auswirkungen sind im Millisekunden bereich.
Als ich die Funktionen miteinander verglich und in eine For Next Schleife steckte, ca. 100 000 aufgerufen, hab.
Ergab sich ein Unterschied von 570 Ms zu 340 Ms für deine Funktion.
An dem kann es nicht liegen. Wen ich die Einzelnen Funktionen teste, ist PureBasic schneller.
Saß gestern 3 Stunden davor um das Problem zu finden.
Bin echt ratlos. Kann es an der Gui liegen ? Irgendwas bremst.
Benute XP Support und Unicode.
Ich weiss, ist echt schwer, darauf eine Anwort geben zu können.

Grüße
Lite