Warum funktioniert .ToInteger hier nicht?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Benutzeravatar
six1
Beiträge: 782
Registriert: Do 1. Jul 2010, 19:01

Re: Warum funktioniert .ToInteger hier nicht?

Beitrag von six1 »

StrToIntDef hast du vergessen... löst keine Meldung aus.
Gruß, Michael

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Warum funktioniert .ToInteger hier nicht?

Beitrag von Warf »

Winni hat geschrieben: Die Funktionen StrToInt, StrToFloatr, TryStrToInt etc benutzen intern alle Val. Dazu lösen sie evtl noch eine Exception aus, die aufwendig mit einem (oder zwei) Try abgefangen werden muss. Aufgeblasener, geschwätzigem Code erzwungenermaßen. Wenn Du wirklich eine Funktion statt einer Procedure für Val benötigst, schnitzt Du Dir das mit 4 Zeilen:
Deshalb hab ich ja auch von TryStrToInt gesprochen, nicht von StrToInt, denn, wie ich geschrieben habe, gibt es Situationen in denen mann den fehler direkt abfangen will, und da sind exceptions kein guter weg für.

Und das TryStrToInt val intern benutzt ist herzlich egal wenns um die leserlichkeit von meinem eigenen code geht. Es ist sogar ein Zeichen das es anscheinend genug leute gibt die der meinung sind das val zu unleserlich ist, sodass es ein wrapper mit besseren Namen und als funktion direkt in der RTL implementiert wurde

Mit deinem Str2Int hast du also lediglich TryStrToInt neu erfunden

Benutzeravatar
Ally
Beiträge: 263
Registriert: Do 11. Jun 2009, 09:25
OS, Lazarus, FPC: Win und Lazarus Stable release
CPU-Target: x64

Re: Warum funktioniert .ToInteger hier nicht?

Beitrag von Ally »

Aufgeblasener, geschwätzigem Code...
Das entspricht nicht meinen Erfahrungen.
Programme die ich auf .ToString und .ToInteger umgestellt habe waren alle kleiner als vorher.
Zwar handelt es sich meist nur um ein KB, ist aber eben auch nicht aufgeblasener.
Und sogar die Performance ist besser. Auch hier reicht es nicht ganz um die Klimakrise aufzuhalten, ist aber eben auch nicht langsamer.

Bleibt noch die Lesbarkeit und die Größe des Codes und da kann ich nur noch mal auf das von Warf und mir schon gesagte verweisen.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  i, intX, Start, Stopp: Integer;
  strNum: String;
begin
  Start := GetTickCount64;
  for i := 1 to 10000 do
  begin
    strNum := i.ToString;
    intX := strNum.ToInteger;
    Label1.Caption := intX.ToString;
  end;
  Stopp := GetTickCount64;
  ShowMessage((Stopp - Start).ToString + ' milliseconds');
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  i, intX, Start, Stopp: Integer;
  strNum: String;
begin
  Start := GetTickCount64;
  for i := 1 to 10000 do
  begin
    strNum := IntToStr(i);
    val(strNum, intX);
    Label1.Caption := IntToStr(intX);
  end;
  Stopp := GetTickCount64;
  ShowMessage((Stopp - Start).ToString + ' milliseconds');
end;
Gruß Roland

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Warum funktioniert .ToInteger hier nicht?

Beitrag von Winni »

Warf hat geschrieben:
Sa 2. Apr 2022, 16:05

Mit deinem Str2Int hast du also lediglich TryStrToInt neu erfunden
Nee, das hab ich schon hab ich schon in den 80gern mit UCSD Pascal und TurboPascal gemacht.

Da gab es TryStrToInt und Delphi noch garnicht.

Wenn Du Deine Polemik zuück haben willst, dann könnte ich sagen:

Delphi hat bei mir geklaut.

PascalDragon
Beiträge: 825
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Warum funktioniert .ToInteger hier nicht?

Beitrag von PascalDragon »

Ally hat geschrieben:
Fr 1. Apr 2022, 18:26
So etwas schönes wie:

Code: Alles auswählen

intX := Edit1.Text.ToInteger;
// oder
strS := Edit1.Text.Substring(1, 2);
// oder
intX := Edit1.Text.Substring(1, 2).ToInteger;
geht halt nicht.
Das liegt daran, dass TEdit.Text vom Typ TTranslateString ist, welcher als type String deklariert ist. Dadurch wird der String-Helper ausgehebelt.
BeniBela hat geschrieben:
Sa 2. Apr 2022, 09:45
Aber wenn man in den Code guckt, macht TryStrToInt nur eine Kopie vom String und ruft damit Val auf. Das ist unnötig langsam.
Keine Ahnung was für 'nen Code du anschaust, aber ich sehe eine Kopie weder in 3.2.2 noch in main:

Code: Alles auswählen

function TryStrToInt(const s: string; out i : Longint) : boolean;
var Error : word;
begin
  Val(s, i, Error);
  TryStrToInt:=Error=0
end;
Winni hat geschrieben:
Sa 2. Apr 2022, 13:27
Die Funktionen StrToInt, StrToFloatr, TryStrToInt etc benutzen intern alle Val. Dazu lösen sie evtl noch eine Exception aus, die aufwendig mit einem (oder zwei) Try abgefangen werden muss.
Wenn man die Try*-Funktionen nutzt, wird keine Exception ausgelöst.
Ally hat geschrieben:
Sa 2. Apr 2022, 16:24
Aufgeblasener, geschwätzigem Code...
Das entspricht nicht meinen Erfahrungen.
Programme die ich auf .ToString und .ToInteger umgestellt habe waren alle kleiner als vorher.
Zwar handelt es sich meist nur um ein KB, ist aber eben auch nicht aufgeblasener.
Und sogar die Performance ist besser. Auch hier reicht es nicht ganz um die Klimakrise aufzuhalten, ist aber eben auch nicht langsamer.
Das war dann aber wahrscheinlich was anderes, da zwar TStringHelper.ToInteger als inline deklariert ist, dieses aber letztlich einfach nurStrToInt aufruft (ohne inlining), welches wiederum TryStrToInt aufruft und wenn nötig eine Exception auslöst. Das heißt der Code sollte durch Verwendung von TStringHelper.ToInteger nicht kleiner werden.
FPC Compiler Entwickler

BeniBela
Beiträge: 308
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Warum funktioniert .ToInteger hier nicht?

Beitrag von BeniBela »

PascalDragon hat geschrieben:
Sa 2. Apr 2022, 21:43


Keine Ahnung was für 'nen Code du anschaust, aber ich sehe eine Kopie weder in 3.2.2 noch in main:

Ich meinte, das ruft ein Val auf, das eine Kopie macht und ein anderes Val aufruft.

Antworten