Seite 3 von 6

Verfasst: 11.10.2006 15:57
von NicTheQuick
@Kaeru:
Falscher Thread?

@all:
Kann mir jemand sagen, warum ich sogar hier einen bescheuerten Fehler
bekomme? Ich glaube Purebasic ist bei Doubles und Quads in Procedures noch ziemlich verbugt.

Außerdem funktioniert das hier nicht:

Code: Alles auswählen

unit = 1
Debug PeekS(@"KBMBGBTBPBEBZBYB" + 1 * 2, 2)
Debug PeekS(@"KBMBGBTBPBEBZBYB" + unit * 2, 2)
An diesem Code ist nichts falsch, trotzdem gibt es zwei Bugs...

Code: Alles auswählen

Procedure.s ByteCalc(Bytes.d, NbDecimals.l = 0)
  Protected result.s, unit.l
  
  unit = Round(Log(Bytes) / Log(1024), 0)
  Bytes / Pow(1024, unit)
  
  If unit
    result = StrD(Bytes, NbDecimals) + " " + PeekS(@"KBMBGBTBPBEBZBYB" + unit * 2 - 2, 2)
  Else
    result = StrD(Bytes, 0) + " B"
  EndIf
  
  ProcedureReturn result
EndProcedure

Debug ByteCalc(21456985147)
Debug ByteCalc(21456985147, 1)
Debug ByteCalc(21456985147, 2)
Debug ByteCalc(21456985147, 4)
Debug ByteCalc(1024 * 1024 - 500, 4)
Debug ByteCalc(512, 1)
Wenn es bei irgendjemandem laufen sollte,
dann liegt es wirklich an irgend einer fehlerhaften Konfiguration von mir.
Aber probiert erstmal aus.

Verfasst: 11.10.2006 16:05
von ts-soft
Bist sicher, das dies Korrekt ist:

Code: Alles auswählen

PeekS(@"KBMBGBTBPBEBZBYB" + unit * 2 - 2, 2)
Illegal Instruction (executing binary data?) :mrgreen:

Verfasst: 11.10.2006 16:12
von NicTheQuick
Ja, das ist korrekt. Schonmal meinen ersten Code getestet? Da funktioniert
der Codeschnipsel mit Konstanten, aber nicht mit Variablen.

Verfasst: 11.10.2006 16:14
von ts-soft
Stimmt, mit Variable bleibts leer, erste Zeile geht, zweite geht mit Konstanten

Verfasst: 11.10.2006 16:21
von AND51
NicTheQuick hat geschrieben:Wenn es bei irgendjemandem laufen sollte,
dann liegt es wirklich an irgend einer fehlerhaften Konfiguration von mir.
Aber probiert erstmal aus.
Bei mir gibt's nen invalid Memory Access in Zeile 13 (Bei ProcedureReturn).

Aber kannst du nicht einfach mit Mid() arbeiten oder hast du's jetzt auf die volle Performance abgesehen? :wink:

Verfasst: 11.10.2006 16:25
von NicTheQuick
Ja, stimmt, Mid() gibt es ja auch noch. :wink:

Aber dennoch gibt es hier schon wieder einen Bug:

Code: Alles auswählen

Procedure.s ByteCalc(Bytes.d, NbDecimals.l = 0)
  Protected result.s, unit.l
  Static Suffix.s = "KBMBGBTBPBEBZBYB"
  
  unit = Round(Log(Bytes) / Log(1024), 0)
  Bytes / Pow(1024, unit)
  
  If unit
    Debug unit
    result = StrD(Bytes, NbDecimals) + " " + Mid(Suffix, unit * 2 - 1, 2)
  Else
    result = StrD(Bytes, 0) + " B"
  EndIf
  
  ProcedureReturn result
EndProcedure
Wenn man den Inhalt von Suffix direkt bei Mid() einsetzt, funktioniert es
wieder.

Verfasst: 11.10.2006 16:33
von AND51
Tja... Hätt'ste mich ned, hätt'ste Mid nich... :wink:

Tipp: Warum Suffix als Staic deklarieren? :shock: Tut es da nicht auch ein Prot... Hm... Aha, Wenn als Static deklariert, muss es nächstes Mal nicht wieder deklariert werden. genial :allright:

Aber warum setzt du Suffix nicht trotzdem bei Mid() direkt ein?

Verfasst: 11.10.2006 16:42
von Kaeru Gaman
[OT]
NicTheQuick hat geschrieben:@Kaeru:
Falscher Thread?
Kaeru Gaman hat geschrieben:...darum ging es mir. man kann nichts aussagen über die performance von ausdrücken,
solange man nicht weiß, wie sie im endeffekt bei der CPU landen.
ts-soft hat geschrieben:Solange keine Progressbar erforderlich ist :mrgreen: , spielt es wohl eher
eine untergeordnete Rolle
Kaeru Gaman hat geschrieben:hä?

was hattn jetzt Radio Eriwan mit der Chinesischen Kulturrevolution zu tun?
[/OT]

Verfasst: 11.10.2006 17:51
von AND51
Kleiner und schneller geht es gar nicht mehr! :D Jetzt sind wir schon im Elite-bereich angelangt.
Von NickTheQuick inspiriert, habe ich die Log() Idee übernommen - damit es nicht einfach nur abschreiben/abkupfern ist, habe ich mich hingesetzt und nochmal nachgeschaut, was log() bewirkt. Dafür hat NtQ von mir ja auch den Tipp mit Mid() bekommen. :allright:

Code: Alles auswählen

Procedure.s byterechner(byte.q, NbDecimals.b=0) 
   Protected bytes.d=PeekQ(@byte), unit.b=Round(Log(bytes)/Log(1024), 0) 
   ProcedureReturn StrD(Bytes/Pow(1024, unit), NbDecimals*(unit > 0 And 1))+" "+StringField("Byte,KB,MB,GB,TB,PB,EB", unit+1, ",") 
EndProcedure
  • Kleine Verbesserung vorgenommen.
Nur 4 Zeilen Code! Wahnsinn... Davon hätt ich anfangs nur träumen können... :D :allright:


Procedure vs. Macro
Man kann es natürlich als Einzeiler verpacken - hab ich getan. Dann habe ich jeweils diesen Zweizeiler und den Einzeiler nochmal als Macro notiert und alle 4 Versionen 50.000 und 100.000 Mal durchlaufen lassen.
Nachteil bei dem Zweizeiler-Mackro: Man muss mit einer Variablen arbeiten, die nicht wie bei der Procedure protected werden kann.
  • Ergebnisse bei 100.000 Durchläufen auf einem System mit 550 MHz/XP mit der Zahl 5415756379 und 1 nachkommastelle:
    Procedure, 2 Zeiler: 2093 ms
    Procedure, 1 Zeiler: 2474 ms
    Makro, 2 Zeiler: 1722 ms <--- Sieger
    Makro, 1 Zeiler: 1833 ms
Dennoch finde ich die 2 Zeiler Prozedur am besten. Den 2er Makro, der zwar am schnellsten ist, kann nämlich nicht bequem in IF-Abfragen beispielsweise eingebaut werden. Außerdem können Makros generell keine Werte zurückgeben. Makro-Ergebnisse müssen immer in Variablen zwischengespeichert werden. Hingegen vergrößern Procedures nicht den Quellcode und sind einfacherer handzuhaben.

Verfasst: 12.10.2006 09:53
von NicTheQuick
Und wieder mein beliebter Fehler:
Debugger hat geschrieben:Line: 3 - Illegal instruction. (executing binary data?)
Warum hab ich den Fehler wieder und sonst keiner?

Bei mir funktionert es nur ohne das PeekQ(). Jetzt hab ich es aber wohl oft
genug gesagt. :mrgreen:

@AND51: Wieso hast du deine eigene Idee mit Mid() nicht selbst benutzt?
Ich wette, damit ist es sogar noch schneller, weil nicht nach Kommas
gesucht werden muss.

Code: Alles auswählen

Procedure.s byterechner(Byte.q, NbDecimals.l = 0)
   Protected Bytes.d = Byte, unit.l = Round(Log(Bytes) / Log(1024), 0)
   ProcedureReturn StrD(Bytes / Pow(1024, unit), NbDecimals * (unit => 1 And 1)) + " " + Mid("KBMBGBTBPBEB", unit * 2 - 1, 2)
EndProcedure

Debug byterechner(1024 * 1024 - 512, 2)
@all: Und denkt dran. In Doubles passen die Zahlen nicht so genau rein
wie in Quads.