AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Threads hier sinnvoll?

Ein Thema von theomega · begonnen am 17. Okt 2002 · letzter Beitrag vom 18. Okt 2002
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von theomega
theomega

Registriert seit: 18. Jun 2002
684 Beiträge
 
#1

Threads hier sinnvoll?

  Alt 17. Okt 2002, 16:16
Hallo
ich habe ein Programm geschrieben, dass aus mehreren Termen mehrer Geraden / Parablen / sonstiges zeichnet.

Dabei kann der User beliebig viel Terme. Die Terme werden nacheinandere ausgerechnet und auch gleich gezeichnet. Bei Zeichnen wiederumm werden erst die Zahlen von 0 abwärts und dann die von 0 aufwärst bearbeitet.

Nun mein Problem: Das Programm ist seeeeeehr langsam.

Jetzt habe ich mich gefragt, ob mit hier Threads etwas bringen würde, zum Beispiel, die positive und die negative Berechung trennen oder jeder Term.

Danke

TO
  Mit Zitat antworten Zitat
Benutzerbild von Salomon
Salomon

Registriert seit: 9. Jun 2002
453 Beiträge
 
#2
  Alt 17. Okt 2002, 16:23
Hallo,
ich denke Threads bringen bei deinem Problem nicht sonderlich viel.
Nur wenn das Programm bei der Berechnung hängt, würde ich sie in einen Thread auslagern.

Ich würde das Programm beschleunigen, indem ich bei Parabeln z.B nur eine gewisse Anzahl an Punkten berechnen würde.

Mfg
Salomon
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.105 Beiträge
 
Delphi 11 Alexandria
 
#3
  Alt 17. Okt 2002, 18:02
Moin The Omega,

wie werden denn Die Terme übergeben?
Wenn Du dazu Strings verwendest, kann das schon massiv auf die Geschwindigkeit gehen, wenn man die normalen Delphi Möglichkeiten benutzt.
Welchen Datentyp verwendest Du denn für die eigentlichen Berechnungen?
Werden viele eigene Funktionen benutzt?
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Benutzerbild von theomega
theomega

Registriert seit: 18. Jun 2002
684 Beiträge
 
#4
  Alt 17. Okt 2002, 18:50
oki, ich poste hier mal den haupteil meines codes: (Erklärung der Veriablen weiter unten)

Code:
procedure geradezeichnen(term:string; index: integer; farbe: TColor;
canvas: Tcanvas;stringgrid:TStringgrid;gauge: TGauge);
var i,counter: integer;
    wert: extended;
    wertalt: extended;
    temp:integer;
begin;
canvas.Pen.color := farbe;

StringGrid.Cells[index,0] := term;

counter := 0;
x:=0;
wert := termtoreal(term);

if (von < 0) then temp := von*divi*-1
else temp := von*divi;

//Negativ
for i:= 1 downto (von*divi) do  begin;
//Berechnen des Wertes
x:=(i-1)/divi;
wertalt := termtoreal(term);
//Fertig

//Eintragen und zeichnen des Wertes
if nodraw = false then begin;
canvas.MoveTo(ileft+round((i*multi)/divi),itop-round(wert*multi));
canvas.lineTo(ileft+round(((i-1)*multi)/divi),itop-round(wertalt*multi));
end;
//StringGrid.Cells[0,temp - counter +2] := floattostr(i/divi);
StringGrid.Cells[index,temp - counter +2] := floattostr(wert);
//Fertig

wert := wertalt;

gauge.Progress := gauge.Progress+1;
inc(counter);

if pm then application.ProcessMessages;

end;

end;

counter := temp+2;

x:=0;
wertalt := termtoreal(term);

//Positiv
for i:= 0 to bis*divi do  begin;
//Berechnen des Wertes
x:=i/divi;
wert := termtoreal(term);
//Fertig

//Eintragen und zeichnen des Wertes
if nodraw = false then begin;
canvas.MoveTo(ileft+round((i*multi)/divi),itop-round(wert*multi));
canvas.lineTo(ileft+round(((i-1)*multi)/divi),itop-round(wertalt*multi));
end;
//StringGrid.Cells[0,counter-1] := floattostr(i/divi);
StringGrid.Cells[index,counter-1] := floattostr(wert);
//Fertig

wertalt := wert;

gauge.Progress := gauge.Progress+1;
inc(counter);

if pm then application.ProcessMessages;

end;
end;
end;
also hier die Erklärungen:
term: der Term, z.b. "2x+4"
index: irrelevant (zum Eintragen in ein Stringgrid)
farbe: Linien Farbe

divi: der Divisor, gibt an, auf wieviele Teile genau gerrechnet werden soll. Ist der divi zum Beispiel 1000 so wird jedes Tausendesl ausgerechnet un gezeichnet.

von: Zahlenbereich von
bis: Zahlenbereich bis

nodraw: soll gezeichnet werden?
ileft: x Koordinaten des Mittelpunkts (0|0)
multi: Zoom, Multi von 2 vergrößert das Bild um das Doppelte
itop: y Koordianten des Mittelpunkts (0|0)

wert: ausgerechneter Wert
wertalt: letzter berechneter Wert (zwecks Linienzeichnung)
counter: irrelevant (zum Eintragen in ein Stringgrid)
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#5
  Alt 17. Okt 2002, 23:24
Ich habe mir jetzt Deinen Code nicht angeschaut es ist einfach zu spät.

Aber mla kurz zu Threads. Generell bringen Thread eigentlich nur ein zwei Situationen einen Vorteil.

1. Das Programm "friert" ein, während aufwendiger Berechnungen.
2. Das Programm läuft auf einem Mehrprozessorsystem.

Auf einem Einprozessorsystem wird der Programmablauf auf jeden Fall langsamer, aber eine "nicht eingefrorene" Applikation mag dieses rechtfertigen. Je mehr Threads, destso größer der Overhead, welcher vom OS aufgebracht werden muss, um diese zu verwalten.
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.105 Beiträge
 
Delphi 11 Alexandria
 
#6
  Alt 18. Okt 2002, 00:33
Moin The Omega,

ich hab' mir das mal angeschaut, und mir sind da ein paar Dinge aufgefallen.
Erst einmal zum Geschwindigkeitsproblem:
TermToReal wird in einer Schleife aufgerufen, und verarbeitet den String term.
String Ver- bzw. Bearbeitung kann ziemlich zeitaufwändig sein. Deshalb ist es durchaus möglich, dass TermToReal eine Bremse ist.
Desweiteren, was hier nicht zu erkennen ist, könnte es von Vorteil sein den Parameter in TermToReal als const zu deklarieren (wenn möglich).

Was mich noch interessieren würde:
Funktioniert das so?
Als ich versucht habe den Code zu strukturieren, damit ich ihn besser lesen kann, fiel mir auf, dass die Procedure eigentlich vor der Zeile counter := temp+2; endet. Diese und der Rest werden nicht mehr verarbeitet. Als ich mal versucht habe das Ganze zu compilieren, war der Compiler der gleichen Ansicht
Meldung: Deklaration erwartet, aber Bezeichner 'counter' gefunden.
BTW:
Warum machst Du eigentlich hinter jedem Begin ein ; ?

Was übrigens den Code noch leichter lesbar machen würde, wären Präfixe bei den Variablen, den Typ angeben, z.B. i für Integer, e für Extended oder auch s für String.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Benutzerbild von theomega
theomega

Registriert seit: 18. Jun 2002
684 Beiträge
 
#7
  Alt 18. Okt 2002, 13:21
warum der Code nicht läuft hat diesen Grund: ich habe ein Paar Zeilen rausgeschmissen, mit Funktionen, die noch nicht funktionieren oder die hier nicht relevant sind, vermutlich ist halt noch ein end zuviel oder zuwenig drine.
Der Code läuft ja, nur halt langsam. Aber evtl. habt ihr recht und es liegt an meiner TermtoReal funktion. Hier mal die gesamte Funktion:
Code:
function pos0(c:char;s:string):integer;
//pos0 findet das Zeichen "+","-" ... nicht innerhalb von Klammern
  var k,z:integer; //z:=Anzahl der Klammern
begin
  z:=0;
  for k:=1 to length(s) do Begin
    if s[k]='(' then inc(z);
    if s[k]=')' then dec(z);
    if (z=0) and (s[k]=c) then BEgin
      result:=k; //Treffer
      exit;
    ENd;
  End;
  result:=0; //nichts gefunden
end;


function anfang(s:string;c:char):string;
begin
  anfang:=copy(s,1,pos0(c,s)-1);
end;

function copyab(const s:string; const i:integer):string;
  begin result:=copy(s,i,length(s)-i+1) end;

function ende(s:string; c:char):string;
begin
  ende:=copyab(s,pos0(c,s)+1)
end;

function hoch(x,y:real):real;
begin
  result:=Power(x,y); //=e      = (e  ) =x
end;

function Wurzel(Value, WurzelNum: Extended): Extended;
begin

try
Result := Power(Value, 1 / WurzelNum)
except
result := 0;
end;

end;

function sinus( aWinkel : extended ) : extended;
begin
  Result:= sin( DegToRad(aWinkel) );
end;

function cosinus( aWinkel : extended ) : extended;
begin
  Result:= cos( DegToRad(aWinkel) );
end;

function tangens( aWinkel : extended ) : extended;
begin
  Result:= tan( DegToRad(aWinkel) );
end;

function TermToReal(s:string):real;
//  {Bisher '+' '-' '*' '/' Klammern und 'x' integriert,
//   d.h. gebrochen rationale Funktionen werden ausgewertet
begin
  //showmessage(s); Empfehlenswert zum Verständnis
  if pos0('+',s)>0  then result:=TermToReal(anfang(s,'+'))+TermToReal(ende(s,'+')) else
  if pos0('-',s)>0  then result:=TermToReal(anfang(s,'-'))-TermToReal(ende(s,'-')) else
  if pos0('*',s)>0 then result:=TermToReal(anfang(s,'*'))*TermToReal(ende(s,'*')) else
  if pos0('/',s)>0 then result:=TermToReal(anfang(s,'/'))/TermToReal(ende(s,'/')) else
  if pos0('^',s)>0 then result:=hoch(TermToReal(anfang(s,'^')),TermToReal(ende(s,'^'))) else
  if pos0('$',s)>0 then result:=wurzel(TermToReal(anfang(s,'$')),TermToReal(ende(s,'$'))) else
  if pos0('s',s)>0 then result:=sinus(TermToReal(ende(s,'s'))) else
  if pos0('c',s)>0 then result:=cosinus(TermToReal(ende(s,'c'))) else
  if pos0('t',s)>0 then result:=tangens(TermToReal(ende(s,'t'))) else

  if (s>'') and (s[1]='(') then Begin //Am Anfang und Ende eine Klammer
    s:=copy(s,2,length(s)-2);
    result:=TermToReal(s)
  End else
  if s='x' then result:=x else //oder TermToReal(Form1.Ex.text)
  result:=StrToFloat(s);
end;
der Code stammt alleridngs nicht von mir, sondern aus dem INet, wer einen besseren hat, nur her damit!
Dieser hier hat eh mehrer Fehler. So erkennt er z.b. "2x" nicht und auch ein Minus am Anfang führt zum Abbruch!
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.105 Beiträge
 
Delphi 11 Alexandria
 
#8
  Alt 18. Okt 2002, 15:49
Moin The Omega,

Probiers mal hiermit.

Code:
[color=#000080]// Grob getestet 70% der Laufzeit der original Pos0[/color]
[b]function[/b] pos0([b]const[/b] c:char;[b]const[/b] s:[b]string[/b]):integer;
[color=#000080]//pos0 findet das Zeichen "+","-" ... nicht innerhalb von Klammern[/color]
  [b]var[/b] k,z:integer; [color=#000080]//z:=Anzahl der Klammern[/color]
[b]begin[/b]
  z := 0;
  [b]for[/b] k:=1 [b]to[/b] length(s) [b]do[/b]
  [b]begin[/b]
    [b]if[/b] s[k]='(' [b]then[/b]
    [b]begin[/b]
      inc(z);
      continue;
    [b]end[/b];
    [b]if[/b] s[k]=')' [b]then[/b]
    [b]begin[/b]
      dec(z);
      continue;
    [b]end[/b];
    [b]if[/b] (z=0) [b]and[/b] (s[k]=c) [b]then[/b]
    [b]begin[/b]
      result:=k;
      exit;
    [b]end[/b];
  [b]end[/b];
  Result := 0;
[b]end[/b];

[b]function[/b] copyab([b]const[/b] s:[b]string[/b]; [b]const[/b] i:integer):[b]string[/b];
[b]begin[/b]
  Result:=copy(s,i,length(s)-i+1)
[b]end[/b];

[b]function[/b] TermToReal(s:[b]string[/b]):real;
[color=#000080]//  {Bisher '+' '-' '*' '/' Klammern und 'x' integriert,[/color]
[color=#000080]//   d.h. gebrochen rationale Funktionen werden ausgewertet[/color]
[b]begin[/b]
  [color=#000080]//showmessage(s); Empfehlenswert zum Verständnis[/color]
  [b]if[/b] pos0('+',s)>0  [b]then[/b] result:=TermToReal(copy(s,1,pos0('+',s)-1))+TermToReal(copyab(s,pos0('+',s)+1)) [b]else[/b]
  [b]if[/b] pos0('-',s)>0  [b]then[/b] result:=TermToReal(copy(s,1,pos0('-',s)-1))-TermToReal(copyab(s,pos0('-',s)+1)) [b]else[/b]
  [b]if[/b] pos0('*',s)>0 [b]then[/b] result:=TermToReal(copy(s,1,pos0('*',s)-1))*TermToReal(copyab(s,pos0('*',s)+1)) [b]else[/b]
  [b]if[/b] pos0('/',s)>0 [b]then[/b] result:=TermToReal(copy(s,1,pos0('/',s)-1))/TermToReal(copyab(s,pos0('/',s)+1)) [b]else[/b]
  [b]if[/b] pos0('^',s)>0 [b]then[/b] result:=Power(TermToReal(copy(s,1,pos0('^',s)-1)),TermToReal(copyab(s,pos0('^',s)+1))) [b]else[/b]
  [b]if[/b] pos0('$',s)>0 [b]then[/b]
  [b]begin[/b]
    [b]try[/b]
      result:=Power(TermToReal(copy(s,1,pos0('$',s)-1)),1/TermToReal(copyab(s,pos0('$',s)+1)));
    [b]except[/b]
      Result := 0;
    [b]end[/b];
  [b]end[/b]
  [b]else[/b]
  [b]if[/b] pos0('s',s)>0 [b]then[/b] result:=sin(DegToRad(TermToReal(copyab(s,pos0('s',s)+1)))) [b]else[/b]
  [b]if[/b] pos0('c',s)>0 [b]then[/b] result:=cos(DegToRad(TermToReal(copyab(s,pos0('c',s)+1)))) [b]else[/b]
  [b]if[/b] pos0('t',s)>0 [b]then[/b] result:=tan(DegToRad(TermToReal(copyab(s,pos0('t',s)+1)))) [b]else[/b]
  [b]if[/b] (s>'') [b]and[/b] (s[1]='(') [b]then[/b] [b]Begin[/b] [color=#000080]//Am Anfang und Ende eine Klammer[/color]
    s:=copy(s,2,length(s)-2);
    result:=TermToReal(s)
  [b]End[/b] [b]else[/b]
  [b]if[/b] s='x' [b]then[/b] result:=x [b]else[/b] [color=#000080]//oder TermToReal(Form1.Ex.text)[/color]
  result:=StrToFloat(s);
[b]end[/b];
Das müsste eigentlich spürbar schneller werden.

Ich hab' einige Funktionsaufrufe direkt in TermToReal übernommen (linearisiert), dadurch fallen die hier jetzt nicht mehr enthaltenen Funktionen weg, ausserdem hab' ich noch Pos0 ein wenig überarbeitet.
Die Funktion CopyAb macht allerdings Sinn, da hierdurch ein zweimaliger Aufruf von Pos0 entfällt, der wohl deutlich langsamer wäre.

Es würde mich mal interessieren, ob's jetzt tatsächlich Veränderungen bringt.
Eventuell könnte man noch mehr rausholen, wenn man nach jeder Zuweisung an Result in TermToReal direkt ein exit einbaut, auch wenn's das ganze unübersichtlicher macht.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Benutzerbild von theomega
theomega

Registriert seit: 18. Jun 2002
684 Beiträge
 
#9
  Alt 18. Okt 2002, 16:58
sorry Christian, aber die Zeiten sind haargenau gleich geblieben, beides mal 35 Sekunden (mein Programm mißt die Zeit!) Aber netter Nebeneffekt: die EXE wird kleiner (2 kb)
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.481 Beiträge
 
Delphi 10.1 Berlin Professional
 
#10
  Alt 18. Okt 2002, 17:39
Für meine Verhältnisse rufst du pos0 zu oft auf. Probiere es mal mit der von mir veränderten TermToReal-Version:

Code:
[b]function[/b] pos0Ex([b]const[/b] c: Char; [b]const[/b] s: [b]string[/b]; out ResultValue: Integer): Integer;
[b]begin[/b]
  Result := pos0(c, s);
  ResultValue := Result;
[b]end[/b];

[b]function[/b] TermToReal(s:[b]string[/b]):real;
[i]//  {Bisher '+' '-' '*' '/' Klammern und 'x' integriert,
//   d.h. gebrochen rationale Funktionen werden ausgewertet[/i]
[b]var[/b] ps: Integer;
[b]begin[/b]
  [i]//showmessage(s); Empfehlenswert zum Verständnis[/i]
  [b]if[/b] pos0Ex('+',s,ps)>0 [b]then[/b] result:=TermToReal(copy(s,1,ps-1))+TermToReal(copyab(s,ps+1)) [b]else[/b]
  [b]if[/b] pos0Ex('-',s,ps)>0 [b]then[/b] result:=TermToReal(copy(s,1,ps-1))-TermToReal(copyab(s,ps+1)) [b]else[/b]
  [b]if[/b] pos0Ex('*',s,ps)>0 [b]then[/b] result:=TermToReal(copy(s,1,ps-1))*TermToReal(copyab(s,ps+1)) [b]else[/b]
  [b]if[/b] pos0Ex('/',s,ps)>0 [b]then[/b] result:=TermToReal(copy(s,1,ps-1))/TermToReal(copyab(s,ps+1)) [b]else[/b]
  [b]if[/b] pos0Ex('^',s,ps)>0 [b]then[/b] result:=Power(TermToReal(copy(s,1,ps-1)),TermToReal(copyab(s,ps+1))) [b]else[/b]
  [b]if[/b] pos0Ex('$',s,ps)>0 [b]then[/b]
  [b]begin[/b]
    [b]try[/b]
      result:=Power(TermToReal(copy(s,1,ps-1)),1/TermToReal(copyab(s,ps+1)));
    [b]except[/b]
      Result := 0;
    [b]end[/b];
  [b]end[/b]
  [b]else[/b]
  [b]if[/b] pos0Ex('s',s,ps)>0 [b]then[/b] result:=sin(DegToRad(TermToReal(copyab(s,ps+1)))) [b]else[/b]
  [b]if[/b] pos0Ex('c',s,ps)>0 [b]then[/b] result:=cos(DegToRad(TermToReal(copyab(s,ps+1)))) [b]else[/b]
  [b]if[/b] pos0Ex('t',s,ps)>0 [b]then[/b] result:=tan(DegToRad(TermToReal(copyab(s,ps+1)))) [b]else[/b]
  [b]if[/b] (s<>'') [b]and[/b] (s[1]='(') [b]then[/b] [b]begin[/b] [i]//Am Anfang und Ende eine Klammer[/i]
    s:=copy(s,2,length(s)-2);
    result:=TermToReal(s)
  [b]end[/b] [b]else[/b]
  [b]if[/b] s='x' [b]then[/b] result:=x [b]else[/b] [i]//oder TermToReal(Form1.Ex.text)[/i]
  result:=StrToFloat(s);
[b]end[/b];
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:10 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz