Seite 2 von 7

Verfasst: 18.11.2006 21:43
von AND51
Jungs, wo bleibt denn bei euch das frei wählbare Tausendertrennzeichen? Oder habe ich das Bild umsonst gepostet? Ich finde, das ist schon ein Bestandteil des "Wettbewerbs" :wink:

Ich werd nochmal meinen Code überarbeiten.

Verfasst: 18.11.2006 21:48
von #NULL
>>...wo bleibt denn...

man füge ein

Code: Alles auswählen

, sep.s="."
ein, und ändere ein in ein :praise:

Verfasst: 18.11.2006 22:57
von Hellhound66
Gehts hier um Speed oder um Kompaktheit?

Verfasst: 18.11.2006 23:28
von ts-soft
Hellhound66 hat geschrieben:Gehts hier um Speed oder um Kompaktheit?
AND51 gehts um Effizienz
Das er oftmals davon ausgeht, das, je kürzer, je schneller, weiß ich auch nicht :lol:

Verfasst: 19.11.2006 00:01
von al90
Hier nochmal eine optimiertere routine. Diese ist jetzt ca. doppelt so schnell
wie mein erster vorschlag. :D

Code: Alles auswählen

Procedure.s FormatByteSize(zahl.q)

Protected l.l, y.l, i.l, x.l, z.l, buff$, num$

num$=StrQ(zahl)
buff$=Space(30)
l=Len(num$)
y=l-(l/3)*3

For i=y To l-1
  PokeB(@buff$+z,PeekB(@num$+i))
  z+1 : x+1
  If x=3
    x=0
    If i<>l
      PokeB(@buff$+z,32)
      z+1
    EndIf
  EndIf
Next

ProcedureReturn ReplaceString(Trim(Left(num$,y)+" "+buff$)," ",".")

EndProcedure 

Debug FormatByteSize(1) 
Debug FormatByteSize(12) 
Debug FormatByteSize(123) 
Debug FormatByteSize(1234) 
Debug FormatByteSize(12345) 
Debug FormatByteSize(123456) 
Debug FormatByteSize(1234567) 
Debug FormatByteSize(12345678) 
Debug FormatByteSize(123456789) 
Debug FormatByteSize(1234567890) 
Debug FormatByteSize(4294967295) 
Gehts hier um Speed oder um Kompaktheit?
Nicht nur. Vielmehr auch um Fehlerfreiheit und das ist wohl auch erstmal das wichtigste.
Jungs, wo bleibt denn bei euch das frei wählbare Tausendertrennzeichen?
Oder habe ich das Bild umsonst gepostet? Ich finde, das ist schon ein
Bestandteil des "Wettbewerbs"
Wat jibbet denn zu jewinnen? :lol:

Verfasst: 19.11.2006 00:12
von AND51
al90 hat geschrieben:Wat jibbet denn zu jewinnen? :lol:
Genügt dir mein Respekt etwa nicht? :twisted: ... :lol:

Verfasst: 19.11.2006 00:24
von AND51
ts-soft hat geschrieben:
Hellhound66 hat geschrieben:Gehts hier um Speed oder um Kompaktheit?
AND51 gehts um Effizienz
Das Stimmt! :D
ts-soft hat geschrieben: Das er oftmals davon ausgeht, das, je kürzer, je schneller, weiß ich auch nicht :lol:
Grrr, das stimmt nicht! :twisted:

_____________________________________________________________


Hier meine optimierte Prozedur:

Code: Alles auswählen

Procedure.s tausendertrennzeichen(zahl.q, separator.s=".")
	Protected zahl$=StrQ(zahl), start.l=Len(zahl$)%3, res.s=PeekS(@zahl$, start), n.l
	For n=start To Len(zahl$)-start-1 Step 3
		res+separator+PeekS(@zahl$+n, 3)
	Next
	ProcedureReturn LTrim(RemoveString(" "+res, " "+separator))
EndProcedure

Debug tausendertrennzeichen(12345678)
Wie gesagt, ich finde, der frei wählbare Separator ist ein unabdingbarer Bestandteil der Prozedur; die drei gängisten Arten, Tausendertrennzeichen zu verwenden sind diese:
Punkt: 123.456.789
Komma: 123,456,789
Hochkomma: 123'456'789
Oder einfach nur L e e r z e i c h e n: 123 456 789


_____________________________________________________________


Ich habe übrigens meine neue Prozedur mit deiner Verglichen, al90.
Ohne Debugger, 3 Mio. durchläufe, pro Durchlauf die Zahlen 123 und 123456789.

AND51: ~20,6 Sek.
al90: ~28,0 Sek.

Verfasst: 19.11.2006 00:26
von #NULL
[@al90]

Bild jetzt auch mit unicode support :) :

Code: Alles auswählen

Procedure.s FormatByteSize(zahl.q)

Protected l.l, y.l, i.l, x.l, z.l, buff$, num$
Protected size=SizeOf(Character)

num$=StrQ(zahl)
buff$=Space(30)
l=Len(num$)
y=l-(l/3)*3

For i=y To l-1
  PokeC(@buff$+z*size,PeekC(@num$+i*size))
  z+1 : x+1
  If x=3
    x=0
    If i<>l
      PokeC(@buff$+z*size,32)
      z+1
    EndIf
  EndIf
Next

ProcedureReturn ReplaceString(Trim(Left(num$,y)+" "+buff$)," ",".")

EndProcedure 

Verfasst: 19.11.2006 00:38
von Hellhound66
Also wenn es um Speed geht, dann würde ich nicht Poke() nutzen, sondern direkt über Pointer arbeiten oder gleich ASM nutzen.

Code: Alles auswählen

i*size
ist auch nicht so toll, warum nicht ne Extravariable, die ich pro Iteration um Size erhöhe?

/Nachtrag:

Code: Alles auswählen

Procedure.s FormatByteSize(zahl.q,ch.s)
    
    Protected l.l, y.l, i.l, x.l, z.l, buff$, num$
    Protected Size=SizeOf(Character)
    
    num$=StrQ(zahl)
    buff$=Space(30)
    l=Len(num$)
    y=l-(l/3)*3
    
    For i=y To l-1
        PokeC(@buff$+z*Size,PeekC(@num$+i*Size))
        z+1 : x+1
        If x=3
            x=0
            If i<>l
                PokeC(@buff$+z*Size,32)
                z+1
            EndIf
        EndIf
    Next
    
    ProcedureReturn ReplaceString(Trim(Left(num$,y)+" "+buff$)," ",ch)
    
EndProcedure    

Procedure.s FormatByteSize2(zahl.q,ch.c)
    Protected l.l, y.l, i.l, x.l, z.l, buff$, num$
    Size=SizeOf(Character)
    
    num$    = StrQ(zahl)
    l       = Len(num$)
    y       = (l-1)/3
    buff$   = Space(l+y+1)
    *BuffPTR.Character = @buff$+(l+y)*Size
    *NumPtr.Character  = @num$+l*Size
    For i=0 To l
        *BuffPTR\C = *NumPtr\C  ;PokeC(@buff$+z*Size,PeekC(@num$+i*Size))
        *BuffPTR - Size
        *NumPtr - Size
        If(x=3)
            If(i=l)
                Break
            EndIf 
            x=0
            *BuffPTR\C = ch     ;PokeC(@buff$+z*Size,32)
            *BuffPTR - Size
        EndIf
        x+1
    Next
    ProcedureReturn buff$
EndProcedure



Delay(500)
#Iterations = 1000000

time.l = ElapsedMilliseconds()
For i = 1 To #Iterations
    FormatByteSize(12345678901234,".")
Next
OldFunc.l = ElapsedMilliseconds()-time

time.l = ElapsedMilliseconds()
For i = 1 To #Iterations
    FormatByteSize2(12345678901234,'.')
Next
NewFunc.l = ElapsedMilliseconds()-time

MessageRequester("SpeedTest","Alte Funktion : "+Str(OldFunc)+#CRLF$+"Neue Funktion : "+Str(NewFunc),#PB_MessageRequester_Ok)
So in der Art meinte ich das.

Verfasst: 19.11.2006 01:09
von AND51
Meine Prozedur unterstützt auch Unicode... :o