PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Exception-Handling (Strings)


pest
2009-04-07, 10:29:37
Eine kurze Frage an die die sich hoffentlich mehr damit auskennen als ich

ich programmiere gerade eine Minischnittstelle zum Verarbeiten einer Excel-Tabelle und in manchen Spalten stehen keine Zahlen drin,
sondern "n/a" oder Ähnliches

erst habe ich die einzelnen Strings manuell geprüft, jetzt mache ich es über Exceptions, habe aber das Gefühl das es dadurch langsamer ist

was ist da die gebräuchliche Vorgehensweise?

Monger
2009-04-07, 10:40:16
In was genau programmierst du denn?

Exception sind relativ rechenaufwändig, weil die u.a. über Reflections den Stacktrace zusammenbasteln.
Das spielt aber normalerweise nicht die Rolle, weil Exceptions nunmal nur "ausnahmsweise" auftreten sollen.

Exceptions sollten nicht für den normalen Codefluss mißbraucht werden. Wenn du schon weißt dass ein gewisser Fall ziemlich regelmäßig auftritt (wie z.B. dass ein String eben nicht zu einer Zahl geparst werden kann), solltest du vorher explizit darauf prüfen bevor du die Wandlung vornimmst.

Wie gesagt:
Exception = Ausnahme. Soll also das abdecken was eher unerwartet ist

pest
2009-04-07, 11:00:12
ich muss in Delphi programmieren

danke für deine Antwort...also Kommando zurück ;)

DocEW
2009-04-07, 11:00:32
Ich würde auch sagen, dass das kein Fall für eine Exception ist. Falls deine Programmiersprache es bietet, könntest du regular expressions verwenden (bspw. in Java: String.matches( ) ).

P.S.: Gibt's in Delphi bestimmt auch.

pest
2009-04-07, 11:17:46
naja auf die Idee bin ich nur aus Bequemlichkeit gekommen, da es zig Varianten für "keine Zahl" gibt...das kommt davon wenn man Daten von Biologen verwerten will :D

um regular expressions in Delphi 5 zu bekommen, muss ich mehr Aufwand betreiben als die 3 Zeilen zum String-Check

Monger
2009-04-07, 11:47:09
Ich kenne das aus Java und .NET so, dass es entweder ein TryParse oder ein IsNumber o.ä. gibt, was dir diesen Schritt abnimmt. Zu erkennen ob ein String eine gültige Zahl ist, kann mitunter ganz schön kompliziert werden.

pest
2009-04-07, 13:05:20
die Beispiele die ich gefunden habe, benutzen entweder Exceptions
oder StrToBool was aber erst seit Delphi 6 geht,
wenn Jmd. was Besseres weiß wäre ich nat. dankbar


Zu erkennen ob ein String eine gültige Zahl ist, kann mitunter ganz schön kompliziert werden.

das stimmt, ich beschränke mich gerade darauf nur zu testen ob ungültige zeichen vorkommen...naja besser als Nichts, oder ich nehm wieder die Exceptions

Delphi :mad:

Der_Donnervogel
2009-04-07, 16:26:58
das stimmt, ich beschränke mich gerade darauf nur zu testen ob ungültige zeichen vorkommen...naja besser als Nichts, oder ich nehm wieder die ExceptionsDas eine schließt das andere ja nicht aus. Eine Möglichkeit wäre es mit einem einfachen Check erst mal alle offensichtlichen Fälle von "Nicht-Zahl" auszusortieren (also z.B. alles das ungültige Zeichen enthält). Damit sollte man (hoffentlich) die meisten "Nicht-Zahlen" erwischt haben und kann dann beim Rest durchaus auf die Methode mit der Exception zurückgreifen. Es sollten dann ja wirklich überwiegend nur noch Zahlen übrig sein und die Ausnahmefälle die durch gerutscht sind, kann man dann ja über Exceptions fangen.

pest
2009-04-07, 16:32:14
lol warum komm ich auf sowas nicht :redface:
danke donnervogel

Gast
2009-04-07, 20:42:46
gebräuchliche vorgehensweise (integer):

try zahl:=strtoint(eingabe_vom_biologen) except zahl:=-1 end;

Statt der -1 kannst du auch sonstwas weitergeben, zB MaxCardinal (bei unsign int) oder so.

Machs net so kompliziert...achja, wärend die Entwicklungsumgebung von Delphi läuft knallts natürlich immer, ohne die IDE wird die -1 brav weitergegeben - was dann bedeutet, dass der nette Biologe Mist eingegeben hat. Und lass Dir nichts vom Pferd erzählen.

pest
2009-04-07, 22:47:21
Machs net so kompliziert


:redface:


...achja, wärend die Entwicklungsumgebung von Delphi läuft knallts natürlich immer,


die brauch ich ständig, habe dafür die Exception "EConvertError" im Debugger ausgeschaltet


Und lass Dir nichts vom Pferd erzählen.

will heißen? das das mit den Exceptions ganz i.O. ist? sind halt ca. 25000 Zahlen, davon vielleicht 100 "n/a"

Der_Donnervogel
2009-04-08, 17:59:02
will heißen? das das mit den Exceptions ganz i.O. ist? sind halt ca. 25000 Zahlen, davon vielleicht 100 "n/a"Bei dem Verhältnis kann man gut mit Exceptions leben. Die können nur dann problematisch werden, wenn sie häufig auftreten, da sie wirklich Performance kosten. Im Zweifelsfall einfach mal einen kleinen Test machen um zu schauen wie viel Performance eine Exception frisst. Dann kann man sich in etwa ausrechnen ab welchem Verhältnis es zu einem Problem kommen kann. zB hab ichs mal spaßhalber schnell mit Java getestet:

public static void main(String[] args) {
long start = System.currentTimeMillis();
int a = 1;
int b = 1;
int num = 1000000;
for (int i = 0; i < num; i++) {
a = a / b;
}
System.out.println((System.currentTimeMillis() - start));
start = System.currentTimeMillis();
b = 0;
for (int i = 0; i < num; i++) {
try {
a = a / b;
} catch (Exception e) {}
}
System.out.println((System.currentTimeMillis() - start));
}

Das Resultat ist, dass die erste Schleife ohne Exception so schnell durchläuft, dass sie am Rande der Messungenauigkeit von currentTimeMillis() liegt. Die zweite Schleife, wo bei jeder Division eine Division-Durch-0-Exception geworfen wird, braucht dagegen auf meinem Laptop ca. 9 Sekunden. :ugly: Vor allem wenn man viele Berechnungen hat und viele Exceptions auftreten würden ist etwas Vorsicht also sicher angebracht.

pest
2009-04-08, 20:29:00
also eine Frage der Verhältnismäßigkeit, nun gut werde ich in Zukunft drauf achten...danke nochmal

nino
2009-04-08, 20:55:52
Es gibt eine Funktion namens StrToIntDef, bei der du einen default-Wert angeben kannst, falls der zu konvertierende String keine Zahl ist. Vielleicht kannst du das ja gebrauchen.

pest
2009-04-08, 21:01:18
gibts die in Delphi5? wäre ja cool :) weil es "StrToFloatDef" auch gibt

Coda
2009-04-08, 22:20:11
wo bei jeder Division eine Division-Durch-0-Exception geworfen wird, braucht dagegen auf meinem Laptop ca. 9 Sekunden. :ugly: Vor allem wenn man viele Berechnungen hat und viele Exceptions auftreten würden ist etwas Vorsicht also sicher angebracht.
Vorsicht. Division durch Null ist eine Hardware-Exception. Kann sehr gut sein, dass das durch den Handler nochmal sehr viel langsamer ist.

Bietchiebatchie
2009-04-09, 01:27:00
(...)
Das Resultat ist, dass die erste Schleife ohne Exception so schnell durchläuft, dass sie am Rande der Messungenauigkeit von currentTimeMillis() liegt. Die zweite Schleife, wo bei jeder Division eine Division-Durch-0-Exception geworfen wird, braucht dagegen auf meinem Laptop ca. 9 Sekunden. :ugly: Vor allem wenn man viele Berechnungen hat und viele Exceptions auftreten würden ist etwas Vorsicht also sicher angebracht.

Ich würde deine Daten etwas anders interpretieren:
Exceptions sind (mittlerweile) so schnell das es eigentlich erst zu Performanceproblemen kommt, wenn man davon mehr als 100000 pro Sekunde wirft; daher sollte es also in den seltesten Fällen zu einem Performanceproblem aufgrund von Exceptions kommen sofern man den alten Grundsatz Exceptions = Ausnahmebehandlung befolgt ;)

pest
2009-04-09, 09:56:27
Es gibt eine Funktion namens StrToIntDef, bei der du einen default-Wert angeben kannst, falls der zu konvertierende String keine Zahl ist. Vielleicht kannst du das ja gebrauchen.

also StrToIntDef gibts in Delphi5 :)
aber leider brauche ich StrToFloatDef was wohl erst mit einer späteren Version verfügbar ist :(
trotzdem danke, ersteres kann ich genauso gebrauchen

Gast
2009-04-09, 13:00:25
also StrToIntDef gibts in Delphi5 :)
aber leider brauche ich StrToFloatDef was wohl erst mit einer späteren Version verfügbar ist :(
trotzdem danke, ersteres kann ich genauso gebrauchen

Es gibt doch Turbo Delphi 6 umsonst inzwischen, ist das nichts für dich? Ist auch kommerziell verwendbar, man kann nur keine VCLs verwenden. Sprich, wenn du Zusatzmodule verwenden willst, musst du sie zur Laufzeit erstellen. Ist aber genauso easy.

Der_Donnervogel
2009-04-09, 14:21:07
Vorsicht. Division durch Null ist eine Hardware-Exception. Kann sehr gut sein, dass das durch den Handler nochmal sehr viel langsamer ist.Ja diese Exception ist noch langsamer als andere Exceptions. Allerdings sind auch andere Excpetions nicht gerade sehr schnell und das wollte ich eigentlich aufzeigen. Man kann ja den Code sehr schnell anpassen, dass er z.B. bei einem b = Integer.valueOf(a) an einer NumberFormatException scheitert. Das Ergebnis ist dann ca. 0,08 Sekunden gegen ca. 2,1 Sekunden. Um es aber klar zu sagen, Exceptions sind ein sehr gutes Konzept, sofern man sie dafür einsetzt wozu sie gedacht sind, nämlich für Ausnahmesituationen.
Ich würde deine Daten etwas anders interpretieren:
Exceptions sind (mittlerweile) so schnell das es eigentlich erst zu Performanceproblemen kommt, wenn man davon mehr als 100000 pro Sekunde wirft; daher sollte es also in den seltesten Fällen zu einem Performanceproblem aufgrund von Exceptions kommen sofern man den alten Grundsatz Exceptions = Ausnahmebehandlung befolgt ;)Auf jeden Fall. Sofern man Exceptions wirklich nur für Ausnahmen einsetzt sollten keine Probleme auftreten. Das kann aber z.B. auch nur von der Art der Eingabedaten abhängen, deshalb hab ich hier nochmal drauf hin gewiesen, dass man etwas aufpassen soll. z.B. bei der Text-zu-Zahl-Konvertierung wird es sehr stark davon abhängen wie hoch der Anteil der Strings ist, die nicht in Zahlen konvertiert werden können. Wenn es beispielsweise darum gehen würde einen Text Wort für Wort zu durchsuchen und die enthaltenen Zahlen rauszupicken, dann wäre eine Lösung die jedes Wort versucht in eine Zahl zu wandeln und bei Nicht-Zahlen, die Exception einfach auffrisst, sicher keine gute Idee.

pest
2009-04-09, 16:12:48
Es gibt doch Turbo Delphi 6 umsonst inzwischen, ist das nichts für dich?


ich mach das "beruflich". Wenn ich es mir aussuchen könnte würde ich C++ nehmen.

mekakic
2009-08-25, 14:50:07
Ich habe mal eine Frage zu Exceptions generell (Java, C++). Für klassische Kontrolllogik sollte man es vermeiden, da die Bearbeitung eben deutlich langsamer ist als einfache Abfragen; und eben nur für das verwenden, was es ist: Ausnahmen. Aber ist es auch langsamer einfach nur nach Exceptions zu schauen? Ist Code, der in einem try-catch-Blöck läuft irgendwie langsamer als Code außerhalb? Immer unter der Voraussetzung, daß eine Exception nicht auftritt.

Monger
2009-08-25, 15:43:50
Aber ist es auch langsamer einfach nur nach Exceptions zu schauen? Ist Code, der in einem try-catch-Blöck läuft irgendwie langsamer als Code außerhalb? Immer unter der Voraussetzung, daß eine Exception nicht auftritt.
Nein. Diese "try/catch" Blöcke sind sowieso nur syntaktischer Zucker. Intern sieht die Ablaufstruktur ganz anders aus, und da läuft es halt so, dass die Methode die eine Exception schmeißt dann in die Fehlerbehandlung rausspringt, die restlichen Informationen über Reflections zusammengesammelt werden, und dann an einen bestimmten Punkt im Speicher hingesprungen wird. Ein Try/Catch ist im Kern also auch nichts anderes als ein Goto - und das frisst nunmal nicht wirklich signifikant Rechenzeit.

Wenn also keine Exception geworfen wird, bist du mit Try/Catch genauso schnell wie ohne. In der Realität wirst du damit eher einen Zacken schneller sein als das klassische Auswerten von Fehlercodes, weil die halt jedes mal und in jedem Zusammenhang gemacht werden.

Wenn eine Exception geworfen wird, ist die (zumindest in Java und .NET) ziemlich rechenintensiv, weil da halt schon standardmäßig eine Menge Diagnoseinformationen drinstecken. Du könntest evtl. das vermeiden, indem du direkt von "throwable" o.ä. erbst, und die Implementierung der Exception Klasse auf diese Weise umgehst, aber das wird den Ärger wahrscheinlich nicht wert sein.

Außerdem: don't optimize (yet)! :tongue:

pest
2009-08-25, 15:45:50
In der Realität wirst du damit eher einen Zacken schneller sein als das klassische Auswerten von Fehlercodes, weil die halt jedes mal und in jedem Zusammenhang gemacht werden.


branch-prediction? (gleich kommt Coda, und sagt, das dies nicht das macht was ich denke :D)

Monger
2009-08-25, 15:55:33
branch-prediction? (gleich kommt Coda, und sagt, das dies nicht das macht was ich denke :D)
Ich glaub, die Frage würde ich tatsächlich gerne Coda überlassen, von Compilern hab ich zu wenig Ahnung! ;)

Aber ich lehn mich mal einfach weit aus dem Fenster, und behaupte dass selbst solche Optimierungen bei Try/Catch weit wirkungsvoller greifen als bei selbstgemachten Friemeleien! ;)

pest
2009-08-25, 16:27:02
Branch Prediction ist Teil moderner Rechnerarchitektur und eben Compiler-Unabhängig

Code-Friemleien musste man früher machen, denn ein Cx6x86 hat bei so einem Konstrukt

ret = funktion
if (ret!=0) do fehlerbehandlung

wirklich Zeit verbraucht