Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Performance im create (https://www.delphipraxis.net/74390-performance-im-create.html)

xZise 2. Aug 2006 13:43


Performance im create
 
Kann man diese funktion schneller machen?

Delphi-Quellcode:
procedure TfrmMain.FormCreate(Sender: TObject);
var Ini : TIniFile;
    s  : String;
    Zeit : Cardinal;
begin
  Zeit := GetTickCount;

  Spectrum            := TSpectrum.Create(pbSVis.Width, pbSVis.Height);
  with Spectrum do
  begin
    PenColor := clBlack;
    Height   := pbSVis.Height;
    PeakColor := clBlack;
  end;

  DoubleBuffered := True;

  Ini := TIniFile.Create(ExtractFilePath(application.exename) + 'settings.ini');
  try
  iVis := Ini.ReadInteger('Settings', 'vis', 3);
  if iVis = 0 then
  begin
    None1.Checked         := True;
    Oscilloscope1.Checked := False;
    SpectrumLines1.Checked := False;
    SpectrumSolid1.Checked := False;
  end;
  if iVis = 1 then
  begin
    None1.Checked         := False;
    Oscilloscope1.Checked := True;
    SpectrumLines1.Checked := False;
    SpectrumSolid1.Checked := False;
  end;
  if iVis = 2 then
  begin
    None1.Checked         := False;
    Oscilloscope1.Checked := False;
    SpectrumLines1.Checked := True;
    SpectrumSolid1.Checked := False;
  end;
  if iVis = 3 then
  begin
    None1.Checked         := False;
    Oscilloscope1.Checked := False;
    SpectrumLines1.Checked := False;
    SpectrumSolid1.Checked := True;
  end;
  xiVolume.Position := Ini.ReadInteger('Settings', 'volume', 50);
  rbSeq.Checked := Ini.ReadBool('Settings', 'sequence', True);
  rbRandom.Checked := Ini.ReadBool('Settings', 'random', False);
  rbLoop.Checked := Ini.ReadBool('Settings', 'loop', False);
  finally
  Ini.Free;
  end;
  with TIniFile.Create(ExtractFilePath(application.exename) + 'settings.ini') do
    try
      FadeTime := ReadFloat('Settings', 'FadeTime', 3);
      FadeOutOnClose := ReadBool('Settings', 'FadeOutOnClose', true);
      //EQSet := ReadInteger('Settings', 'EQSet', 0);
      Crossfade := ReadBool('Settings', 'Crossfade', true);
    finally
      Free;
    end;

  DoubleBuffered := True;
  BASS_Init(1, 44100, 0, Application.Handle, nil);
  BASS_SetConfig(BASS_CONFIG_BUFFER,1000);

  eqTb1.Position   := eqTb1.Max div 2;
  eqTb2.Position   := eqTb2.Max div 2;
  eqTb3.Position   := eqTb3.Max div 2;
  eqReverb.Position := eqReverb.Max;

  DrawSkin;
end;
Delphi-Quellcode:
procedure TfrmMain.DrawSkin;
var
  Skin : TIniFile;
  s : string;
  i : Integer;
begin
  with TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'settings.ini') do
    try
      s := ExtractFilePath(Application.ExeName) + 'skins\' + ReadString('Settings', 'Skin', 'blue.dpsf');
    finally
      Free;
    end;

  if FileExists(s) then begin
    Skin := TIniFile.Create(s);
    try
      xiBg.ColorGrad   := StringToColor(Skin.ReadString('Backgrnd', 'Grad', 'clSkyBlue'));
      xiBg.ColorFace   := StringToColor(Skin.ReadString('Backgrnd', 'Face', '$00FE9741'));
      // Playlist
      lbList.Color     := StringToColor(Skin.ReadString('Playlist', 'Backgrnd', '$00F3C091'));
      lbList.Font.Color := StringToColor(Skin.ReadString('Playlist', 'Font', 'clWindowText'));
      // Top
      xiCaptionBar.ColorFace := StringToColor(Skin.ReadString('Top', 'Face', '$00FF0301'));
      xiCaptionBar.ColorGrad := StringToColor(Skin.ReadString('Top', 'Grad', '$00FE9741'));
      xiCaptionBar.ColorLight := StringToColor(Skin.ReadString('Top', 'Light', '$00F0964D'));
      xiCaptionBar.ColorDark := StringToColor(Skin.ReadString('Top', 'Dark', '$00B35900'));
      xiCaptionBar.Font.Color := StringToColor(Skin.ReadString('Top', 'Font', 'clWindowText'));


      for i := 0 to frmMain.ComponentCount - 1 do begin
        if frmMain.Components[i] is TXiButton then begin
          with (frmMain.Components[i] as TXiButton) do begin
            ColorBorder        := StringToColor(Skin.ReadString('Buttons', 'Border', '$00B35900'));
            ColorDark          := StringToColor(Skin.ReadString('Buttons', 'Dark', '$00FFA851'));
            ColorFace          := StringToColor(Skin.ReadString('Buttons', 'Face', '$00FF953E'));
            ColorFocusRect     := StringToColor(Skin.ReadString('Buttons', 'FocusRect', '$00FFA953'));
            ColorGrad          := StringToColor(Skin.ReadString('Buttons', 'Grad', '$00FFB66C'));
            ColorLight         := StringToColor(Skin.ReadString('Buttons', 'Light', '$00FF953E'));
            ColorText          := StringToColor(Skin.ReadString('Buttons', 'Text', '$00000000'));
            DownColorBorder    := StringToColor(Skin.ReadString('Buttons', 'DownBorder', '$00B35900'));
            DownColorDark      := StringToColor(Skin.ReadString('Buttons', 'DownDark', '$00FFD3A8'));
            DownColorFace      := StringToColor(Skin.ReadString('Buttons', 'DownFace', '$00FFB366'));
            DownColorGrad      := StringToColor(Skin.ReadString('Buttons', 'DownGrad', '$00FFCE9D'));
            DownColorLight     := StringToColor(Skin.ReadString('Buttons', 'DownLight', '$00FF9E3E'));
            DownColorText      := StringToColor(Skin.ReadString('Buttons', 'DownText', '$00000000'));
            OverColorBorder    := StringToColor(Skin.ReadString('Buttons', 'OverBorder', 'clNavy'));
            OverColorDark      := StringToColor(Skin.ReadString('Buttons', 'OverDark', '$00FF9E3E'));
            OverColorFace      := StringToColor(Skin.ReadString('Buttons', 'OverFace', '$00FFB66C'));
            OverColorGrad      := StringToColor(Skin.ReadString('Buttons', 'OverGrad', '$00FFA346'));
            OverColorLight     := StringToColor(Skin.ReadString('Buttons', 'OverLight', '$00FFB66C'));
            OverColorText      := StringToColor(Skin.ReadString('Buttons', 'OverText', '$00000000'));
            DisabledColorBorder := StringToColor(Skin.ReadString('Buttons', 'DisabledBorder', 'clGray'));
            DisabledColorDark  := StringToColor(Skin.ReadString('Buttons', 'DisabledDark', '$00D2D2D2'));
            DisabledColorFace  := StringToColor(Skin.ReadString('Buttons', 'DisabledFace', '$00EEEEEE'));
            DisabledColorGrad  := StringToColor(Skin.ReadString('Buttons', 'DisabledGrad', 'clWhite'));
            DisabledColorLight := StringToColor(Skin.ReadString('Buttons', 'DisabledLight', 'clWhite'));
            DisabledColorText  := StringToColor(Skin.ReadString('Buttons', 'DisabledText', 'clGray'));
          end;
        end else if frmMain.Components[i] is TXiTrackBar then begin
          // Trackbars
          with Components[i] as TXiTrackBar do begin
            ThumbBorderColor := StringToColor(Skin.ReadString('Trackbars', 'ThumbBorder', '$00C66300'));
            ThumbFaceColor := StringToColor(Skin.ReadString('Trackbars', 'ThumbFace', '$00FFD9B3'));
            ThumbGradColor := StringToColor(Skin.ReadString('Trackbars', 'ThumbGrad', '$00FF9224'));
            SlideBorderColor := StringToColor(Skin.ReadString('Trackbars', 'SlideBorder', '$00F47A00'));
            SlideFaceColor := StringToColor(Skin.ReadString('Trackbars', 'SlideFace', '$00FFBA75'));
            SlideGradColor := StringToColor(Skin.ReadString('Trackbars', 'SlideGrad', '$00FFE9D2'));
            OverThumbBorderColor := StringToColor(Skin.ReadString('Trackbars', 'OverThumbBorder', '$00B35900'));
            OverThumbFaceColor := StringToColor(Skin.ReadString('Trackbars', 'OverThumbFace', '$00FFCF9F'));
            OverThumbGradColor := StringToColor(Skin.ReadString('Trackbars', 'OverThumbGrad', '$00F97C00'));
            DownThumbBorderColor := StringToColor(Skin.ReadString('Trackbars', 'DownThumbBorder', '$00B35900'));
            DownThumbFaceColor := StringToColor(Skin.ReadString('Trackbars', 'DownThumbFace', '$00FF8C1A'));
            DownThumbGradColor := StringToColor(Skin.ReadString('Trackbars', 'DownThumbGrad', '$00FFBF80'));
            DisabledThumbBorderColor := StringToColor(Skin.ReadString('Trackbars', 'DisabledThumbBorder', '$00B5B5B5'));
            DisabledThumbFaceColor := StringToColor(Skin.ReadString('Trackbars', 'DisabledThumbFace', '$00EAEAEA'));
            DisabledThumbGradColor := StringToColor(Skin.ReadString('Trackbars', 'DisabledThumbGrad', '$00CFCFCF'));
            DisabledSlideBorderColor := StringToColor(Skin.ReadString('Trackbars', 'DisabledSlideBorder', '$00BEBEBE'));
            DisabledSlideFaceColor := StringToColor(Skin.ReadString('Trackbars', 'DisabledSlideFace', '$00D8D8D8'));
            DisabledSlideGradColor := StringToColor(Skin.ReadString('Trackbars', 'DisabledSlideGrad', '$00E8E8E8'));
            DisabledTickColor := StringToColor(Skin.ReadString('Trackbars', 'DisabledTick', 'clSilver'));
            TickColor := StringToColor(Skin.ReadString('Trackbars', 'Tick', '$00C88D2D'));
          end;
        end else if Components[i] is TShape then begin
          // Ränder
          if Copy((Components[i] as TShape).Name, 1, 3) = 'sLb' then begin
            // d. Playlist
            (Components[i] as TShape).Brush.Color := StringToColor(Skin.ReadString('Playlist', 'Border', '$00B99D7F'));
          end else begin
            // restliche
            (Components[i] as TShape).Brush.Color := StringToColor(Skin.ReadString('Misc', 'Border', '$00FF0301'));
          end;
        end else if Components[i] is TLabel then begin
          (Components[i] as TLabel).Font.Color := StringToColor(Skin.ReadString('Misc', 'Font', '$00000000'));
        end else if Components[i] is TRadioButton then begin
          (Components[i] as TRadioButton).Font.Color := StringToColor(Skin.ReadString('Misc', 'Font', '$00000000'));
        end;
      end;

    finally
      Skin.Free;
    end;

    tColors.Enabled := true;
  end else begin
    Showmessage('Skinfile not found!');
  end;
end;
Delphi-Quellcode:
procedure TfrmMain.tColorsTimer(Sender: TObject);
var
  hDesk : HWND;
  hdcDesktop : HDC;
  crefPixel, cPixel, aPixel, bPixel, z, y: COLORREF;
  p, cp, a, b: TPoint;
begin
  p.X := 15;
  p.Y := 149;

  hDesk := GetDesktopWindow;
  hdcDesktop := GetWindowDC(hDesk);

  crefPixel := GetPixel(hdcDesktop, p.x, p.y);
  eqTb1.BackColor   := crefPixel;
  eqTb2.BackColor   := crefPixel;
  eqTb3.BackColor   := crefPixel;
  eqReverb.BackColor := crefPixel;
  cbEq.Color        := crefPixel;

  cp.X  := 7;
  cp.Y  := 44;
  cPixel := GetPixel(hdcDesktop, p.x, p.y);
  c     := cPixel;

  lTime.Color := c;

  lLauftext.Color := c;


  a.X   := 5;
  a.Y   := 412;
  aPixel := GetPixel(hdcDesktop, a.x, a.y);
  z     := aPixel;

  lbList.Color := z;

  b.X   := 7;
  b.Y   := 304;
  bPixel := GetPixel(hdcDesktop, b.x, b.y);
  y     := bPixel;

  rbSeq.Color   := y;
  rbRandom.Color := y;
  rbLoop.Color  := y;
  cbLbList.Color := y;

  Spectrum.BackColor := c;

  tColors.Enabled := False;
end;

Hawkeye219 2. Aug 2006 16:01

Re: Performance im create
 
Hallo Fabian,

einer erste Verbesserung dürftest du erreichen, wenn du 'TIniFile' durch 'TMemIniFile' ersetzt. Siehe dazu auch diesen Beitrag von marabu.

Die 4 IF-Abfragen in der Methode FromCreate könntest du durch das folgende Codestück ersetzen:

Delphi-Quellcode:
None1.Checked := (iVis = 0);
Oscilloscope1.Checked := (iVis = 1);
SpectrumLines1.Checked := (iVis = 2);
SpectrumSolid1.Checked := (iVis = 3);
Warum schließt du eigentlich das TIniFile, wenn du es anschließend direkt wieder öffnest?

Das Einlesen der Parameter für die Komponenten (Methode DrawSkin) solltest du überdenken. Vielleicht wäre es sinnvoller, die Werte einmalig vor der Schleife zu lesen, anstatt sie für jede Komponente erneut aus der INI-Datei zu holen. StringToColor arbeitet mit einer Suchschleife und ist somit relativ langsam.

Gruß Hawkeye

xZise 2. Aug 2006 16:10

Re: Performance im create
 
Dank erstmal ;)

Zitat:

Zitat von Hawkeye219
Warum schließt du eigentlich das TIniFile, wenn du es anschließend direkt wieder öffnest?

Ich bevorzuge die Methode:
Delphi-Quellcode:
with TIniFile.create(Path) do
  try

  finally
    Free;
  end;
Die Methode davor ist von meinem "Parnter" der stattdessen ehr die Variante nimmt:
Delphi-Quellcode:
Ini := TIniFile.Create(Path)
// do something
Ini.Free;
(PS: Ohne try-finally (leider))

Nun wollte ich es ihm überlassen (eigentlich sollte ich nur den Skineditor machen), ob er jetzt die 1. oder 2. Variante benutzt.
Deshalb gibts das noch und ich denke mal, dass ist auch nicht sehr performant :D Ich werd ihn ansprechen ;)

@ MemIniFile: Wo ist der unterschied zu IniFIle?

Der_Unwissende 2. Aug 2006 17:14

Re: Performance im create
 
Zitat:

Zitat von xZise
MemIniFile: Wo ist der unterschied zu IniFIle?

Schau einfach mal in die OH oder in den Beitrag vom marabu. Der sagt doch da (wenn du auf den link klickst) :
Zitat:

Zitat von marabu
Ein Vorteil von TIniFile ist, dass jeder Schreibzugriff sofort zur Persistenz führt. Einer von vielen Nachteilen ist, dass jeder Lesezugriff zu einem Lesen von der Platte führt

Anders gesagt ein TIniFile schreibt sofort alles auf die Platte, womit marabu auch schon die Vorteile genannt hat. Die Festplatte ist aber nun mal um einiges langsamer als dein RAM und erst recht als deine CPU. Dies gilt auch für die Caches, hier wäre der L2 Cache noch deutlich schneller als dein RAM und der noch viel schneller als der Plattencachezugriff.
Ein TMemIniFile lädt die Ini einfach in eine THashedStringList und die liegt einfach schon im Speicher. Damit ist nicht jedesmal ein Zugriff auf die Festplatte nötig, das bringt beim nur lesenden Zugriff eine ganze Menge. Beim Schreiben musst du beachten, dass du keine Persistenz hast, bevor du update aufrufst. Natürlich ist es sehr sehr viel perfomanter alle Änderungen in einem Rutsch auf die Platte zu schreiben (genau dafür ist die da), aber wenn zwischendrin dein Rechner ausfällt, Pech).

Was deine Schleife angeht, so kannst du einfacher mit ControlCount und Controls arbeiten. Controlls sind dabei einfach die sichtbaren TComponents (also das was du eh nur suchst), dass könnte also ein paar unnötige Operationen ersparen.

Was das Öffnen und das Schließen der Ini angeht, so glaube ich meinte Hawkeye eigentlich etwas anderes als dein try finally Block.

Delphi-Quellcode:
procedure TfrmMain.FormCreate(Sender: TObject);
  Ini := TIniFile.Create(ExtractFilePath(application.exename) + 'settings.ini'); // <- DU ÖFFNEST
  try
   ... // liest
  finally
  Ini.Free; // <- GIBST FREI
  end;

  // LEGST NEU AN
  with TIniFile.Create(ExtractFilePath(application.exename) + 'settings.ini') do
    try
      FadeTime := ReadFloat('Settings', 'FadeTime', 3);
      FadeOutOnClose := ReadBool('Settings', 'FadeOutOnClose', true);
      //EQSet := ReadInteger('Settings', 'EQSet', 0);
      Crossfade := ReadBool('Settings', 'Crossfade', true);
    finally
      Free;
    end;

xZise 2. Aug 2006 19:21

Re: Performance im create
 
Zitat:

Zitat von xZise
Nun wollte ich es ihm überlassen (eigentlich sollte ich nur den Skineditor machen), ob er jetzt die 1. oder 2. Variante benutzt.
Deshalb gibts das noch und ich denke mal, dass ist auch nicht sehr performant :D Ich werd ihn ansprechen ;)

Das sagt doch alles, warum ich 2 mal TIniFile.Create mache?

@ MemIniFile: Allerdings lese ich ja nur Daten = wenn ich einmal 10 Daten lese oder 10 mal eine Date (?) lese macht an sich keinen Unterschied oder?

jfheins 2. Aug 2006 21:24

Re: Performance im create
 
Zitat:

Zitat von xZise
Zitat:

Zitat von xZise
Nun wollte ich es ihm überlassen (eigentlich sollte ich nur den Skineditor machen), ob er jetzt die 1. oder 2. Variante benutzt.
Deshalb gibts das noch und ich denke mal, dass ist auch nicht sehr performant :D Ich werd ihn ansprechen ;)

Das sagt doch alles, warum ich 2 mal TIniFile.Create mache?

So muss die ini 2 mal geladen werden, wenn es dir auf Geschwindigkeit ankommt ist das ... redundant ;)

Zitat:

@ MemIniFile: Allerdings lese ich ja nur Daten = wenn ich einmal 10 Daten lese oder 10 mal eine Date (?) lese macht an sich keinen Unterschied oder?
Doch,einen Großen. Was ist schneller? Zehnmal in die Bücherei laufen, um je ein Buch zu holen, oder einmal in die Bücherei, um 10 Bücher abzuholen ?

Christian Seehase 2. Aug 2006 21:40

Re: Performance im create
 
Moin Zusammen,

Zitat:

Zitat von Der_Unwissende
Beim Schreiben musst du beachten, dass du keine Persistenz hast, bevor du update aufrufst.

weiterhin finde ich beachtenswert, dass beim Schreiben offensichtlich die Sections gelöscht, und dann neu geschrieben werden, so dass eventuell enthaltene Kommentarzeilen nicht erhalten bleiben.

Nils_13 2. Aug 2006 21:41

Re: Performance im create
 
Es geht darum, dass das Programm eine halbe Sekunde benötigt um zu starten, da ein kleines Skinsystem eingebunden ist. Aber wenn ich an Winamp denke, ist das verhältnissmäßig schnell.

xZise 2. Aug 2006 22:03

Re: Performance im create
 
Dann dauert es "nur" 500 ms... Aber warum muss man 500 ms warten, wenns auch 250 ms geht?

Außerdem hat mich dieser Code ein bisschen "gestört", weil das einfach nur irgendwelche aneinander geketteten Zeilen sind...

Ich mein, schon diese if's hätte man mit else verbinden können, aber noch nicht mal dass... Dann fehlte auch das try-finally im 1. IniBlock... Ich werde denn Code mir mal "vorknöpfen" und denn dann verbessern... Auch wenns nur 500 ms dauert!


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:08 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