Hallo,
Ich bin ja nicht so fit in ASM.
Ich bräuchte ein Translate$() für sehr große Bereiche.
Wäre ja evtl. viel schneller, als daß man mit String$()
zuerst einen riesengroßen String erzeugen muß.
Vielleicht hat schon jemand sowas in der Schublade.
Hallo,
Ich bin ja nicht so fit in ASM.
Ich bräuchte ein Translate$() für sehr große Bereiche.
Wäre ja evtl. viel schneller, als daß man mit String$()
zuerst einen riesengroßen String erzeugen muß.
Vielleicht hat schon jemand sowas in der Schublade.
Warum sollte das bei der Nutzung von ASM sehr viel schneller gehen?
Oder welchen Grund hast du, dass du das in ASM brauchst?
Hatten wir schon mal hier.
Damals hatte mir Volkmar was gebastelt.
Das war in ASM auch sehr viel schneller, als die XProfan-Funktion.
Ist ja auch bekannt, daß Delphi's Stringfuntkionen nicht gerade die
schnellsten sind.
Teile den String in Einzelstrings von maximal 10KB Größe auf und ersetze dann mit Translate$ - das geht scheinbar sehr viel schneller.
Ab Strings von 1MB Größe nimmt die Zeit scheinbar exponential zu.
Ich will hoffen, dass ich beim Austesten gerade nichts falsch gemacht habe...
Ab Strings von 1MB Größe nimmt die Zeit scheinbar exponential zu.
So, wie ich es sehe, hängt es an den langsamen Schleifen und nicht mal an der
Größe der Strings.
Declare String A[1000000], z
Mat A[] = "Hallo, du, da !"
CLS
Print "Array ist gefüllt !"
Print "Starte WhileLoop - Test....Taste"
WaitKey
WhileLoopTest()
Print "Starte Move.... Taste"
Waitkey
Set("MoveListMode", 1)
Move("ArrToList", A[])
Print "Move ist fertig..."
Waitkey
Proc WhileLoopTest
WhileLoop 0, SizeOf(A[]) - 1
z = Translate$(A[&LOOP], ",", "|")
EndWhile
Print "WhileLoop ist fertig"
EndProc
MoveListProc
Parameters String s, int index
Declare String z
If Get("MoveListMode") = 1
z = Translate$(s, ",", "|")
EndIf
EndProc
Alles anzeigen
Sogar die MoveListProc scheint langsamer zu sein.
Doch - hängt an der Größe des Strings. Bei meiner Technik brauche ich für einen String von 1,3MB Größe mit reinem Translate$ 80 Sekunden - mit meiner Technik 0,655 Sekunden.
Erhöhe ich die Stringlänge auf 2,6MB, braucht Translate$ bei mir 327 Sekunden, meine Technik ist in 2,3 Sekunden fertig.
Verdoppele ich den String nochmals auf 5,2MB, braucht Translate$ bei mir 29 Minuten (1768 Sekunden), meine Technik ist in 7,4 Sekunden fertig.
Optimale Größe für Translate$ scheint hier etwa 5KB an Stringgröße zu sein. Dann reagiert das Fenster noch vernünftig auf Messages und die Anzahl der Schleifendurchläufe sind noch nicht so groß, dass die ganze Sache Ewigkeiten dauert.
Ich denke, er sucht nach einer Lösung, die Frank in seiner Listview.dll eingebaut hat.
Tausch von Trennzeichen in einer csv-Datei.
Für 5.931kB braucht die 22/100 sec.
text$="bic.csv"
bytes&=@FileSize(text$)
print "Bytes: "+str$(bytes&)
print "Start:" + @Time$(1)
If bytes&>0
Dim bereich#,bytes&+1
ReadFileQuick(addr(text$),bereich#,0,bytes&)
ExchangeSeparator(bereich#,bytes&,@Ord(";"),@Ord("#"),1)
print "Fertig:"+@Time$(1)
ExchangeSeparator(bereich#,bytes&,@Ord("#"),@Ord(";"),1)
CsvToListview(listview&,bereich#,bytes&,6)
Dispose bereich#
EndIf
print "Zeilen:"+str$(GetLines(listview&))
ShowListView(listview&,2,82,500,450)
Alles anzeigen
Ich denke, er sucht nach einer Lösung, die Frank in seiner Listview.dll eingebaut hat.
Ganz genau.
Das geht so schnell, da kann man keine Zeit messen :
Declare Memory bereich, Long hdll, anz
hdll = UseDLL("Listview.dll")
ImportFunc(hdll, "ExchangeSeparator", "TranslateX")
CLS
Dim bereich, FileSize("E:\Liste.txt")
Assign #1, "E:\Liste.txt"
OpenRW #1
anz = BlockRead(#1, bereich)
Close #1
Print "Fertig..."
Print "Taste zum Austausch"
WaitKey
TranslateX(bereich, FileSize("E:\Liste.txt"), Ord(","),Ord("|"),1)
Print "Fertig..."
Waitkey
Dispose bereich
FreeDLL hdll
End
Alles anzeigen
Dabei ist die Datei 47.744 KB groß.
Das wäre dann aber was ganz Anderes als das "echte" Translate$. Das muß ja auch beliebig viele Strings mit wahlfreier Länge durch einen String mit wahfreier Länge ersetzen und hat dann auch erst mal die neue Ziellänge zu ermitteln, den Speicher entsprechend zuzuweisen und dann nicht nur einzelne Bytes zu ersetzen, es muß ja alle Daten umschaufeln. Soll nur ein einzelnes Byte beliebig oft durch ein anderes Byt ersetzt werden, dann ist das recht einfach.
//TranslateX(Bereich#, Size&, OrgChar%, NewChar%)
ASM "TranslateX", 4
PUSH EBX
PUSH ECX
PUSH EDX
PUSH ESI
MOV EDI, Par1 // Adresse Quellstring
MOV ECX, Par2 // Länge Quellstring
MOV EBX, Par3 // Code Suchzeichen
MOV EDX, Par4 // Code Ersatzzeichen
MOV AL, BL
MOV AH, DL
XOR EDX, EDX // EDX löschen
Suchen:
OR ECX, ECX // Quelllänge 0?
JZ IsLen // Länge 0 erreicht, String durch
DEC ECX // Länge runter zählen
SCASB
JNZ Suchen // Byte nicht gefunden
MOV [EDI - 1], AH // Ersetzen
INC EDX // Ersetzen Zählen (kann entfallen)
JMP Suchen
IsLen:
MOV EAX, EDX
POP ESI
POP EDX
POP ECX
POP EBX
EndASM
Declare Mem Bereich, String Test
Test = "Does ost eon erster Teststrong, on dem was gewechselt word."
DIM Bereich, 1000
String Bereich, 0 = Test
Print Test, Len(Test)
Print Str$(TranslateX(Bereich, Len(Test), Ord("o"), Ord("i"))), " geändert:"
Print String$(Bereich, 0)
WaitInput
Alles anzeigen
Gruß Volkmar
Das geht auch dann flott.
Danke, Volkmar.
Funktioniert super. Brauche es nur, um in großen Bereichen zu ersetzen.
Optimal wäre es, wenn man zwei oder mehr Zeichen ersetzen könnte.
Ansonsten :
Zum Ersetzen von mehr Zeichen würde ich die Sache aufteilen:
Man muss sich natürlich etwas Gedanken darüber machen, wie die ganze Sache wirklich sicher läuft und alles ersetzt.
Bei 5,2MB an String sind 29 Minuten echt die Kanone.
Danke für deinen Beitrag hier. War echt lustig, das mal auszutesten. Arbeite zum Glück seit einiger Zeit nicht mehr wirklich mit XProfan.
Bitte nicht falsch verstehen - ist eine wirklich schöne Sprache zum Lernen von Programmierung unter Windows (wenn man das nicht beruflich braucht), eben weil die Sprache manche Sachen nicht zu einfach macht (und manche eben doch). Zum Schreiben von wirklichen Anwendungen taugt das aber seit Windows7 nicht mehr so wirklich.
XProfan zwingt so zu verdammt guten, durchdachten Algorithmen. Woanders geht´s halt mit Brute Force ...
Erforderlichenfalls kann man auch noch an XPSE denken, dort gibts ein "natives" Translate$(). Bei X4 wird man allerdings sehr viele
{$PUSHKEYWORD param} brauchen, will man nicht ganz brutal mit {$NOERR} arbeiten. Mit dem Schalter kann man - beistrichgetrennt - Schlüsselworte als existent definieren, die XProfan 11 noch nicht kannte. Und um mit FOR NEXT und Quadint zu arbeiten, gibt es die JRPC.exe als Prä-Precompiler für iF´s XPSE mit X2 und X3, ich vermute aber auch mit X4: Link
Bevor man zig andere Tools nutzt - die im Endeffekt auch nicht dazu führen, dass alles in der Sprache wirklich vernünftig funktioniert - ist es besser und einfacher (und billiger), eine andere Sprache zu nehmen (wenn man wirklich Anwendungen schreiben möchte).
XProfan ist klasse, wenn man bestimmte Sachen tun möchte. Will man wirklich Programme schreiben, ist man besser bei anderen Sprachen aufgehoben.
Interessant: Translate besteht ja aus t$[]=explode(string$,",") und x$=implode$(t$[],"|neuerTrenner|").
Explode ist sehr flott, aber im Implode wird je neuem angehängtem Trenner ein String x$ erweitert. Das gibt bei 20000 Trennern 20000 neue Strings - gegen Ende jedesmal fast die volle Länge. HIER müsste man was machen mit ASM - nur müsste man dazu wissen, wie die Stringarrays angesprochen werden (statisch oder dynamisch macht auch noch einen Unterschied!
XProfan zwingt so zu verdammt guten, durchdachten Algorithmen.
Dazu noch:
Im Prinzip empfinde ich das heutzutage eher als nervig, da viele Sachen davon in anderen Sprachen gar nicht oder in anderer Art nötig sind.
Von ihrem Aufbau halte ich die Sprache immer noch für absolut gut.
So was hier entwickele ich zuerst immer noch mit XProfan unter 32Bit:
Bei XProfan (gerade bei meiner älteren Version) muss ich mir zum Entwickeln solcher Sachen sehr viel mehr durchlesen (und wirklich verstehen) als ich das in der Sprache muss, in der ich das dann verwendet habe (ist im PPFScanner eingebaut).
Wenn etwas nicht läuft (das war natürlich auch bei der Entwicklung dieser Sache so), weiß ich dann sehr genau, warum es so nicht geht und ob ich etwas anderes tun kann, damit der Code am Ende funktioniert.
Ich habe also am Anfang zwar sehr viel mehr Arbeit, habe aber wesentlich größere Chancen, am Ende etwas zu haben, was funktioniert.
Im Endeffekt sind dann aber mit XProfan gar keine Programme wirklich machbar, in denen man so etwas richtig nutzen kann. Da man aber dann verstanden hat, was man da getan hat, ist auch die Umsetzung in andere Sprachen und auf 64Bit kein Problem.
Sehr interessant finde ich auch, das XProfan eine interpretierende Sprache ist. Man muss die ja gar nicht nur dazu nutzen, um eigenständige Programme zu schreiben.
HIER müsste man was machen mit ASM
Man müsste gar nichts. Die Sprache ist im Prinzip zum Entwickeln von Anwendungen seit Vista tot.
Jetzt möchte ich mich auch mal einmischen: Sinnhaftigkeit hin oder her, es hilft uns doch nicht weiter wenn immer wieder erwähnt, dass andere Sprachen schneller und besser sind.
Leider ist das Problem damit nicht gelöst
Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!