[BCB 5] Ontzettend trage executable

Pagina: 1
Acties:

  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 25-05 15:58

Bergen

Spellingscontroleur

Topicstarter
Ik werk al sinds jaar en dag in Delphi en omdat ik veel grafische dingetjes maak dacht ik: laat ik C++ Builder eens proberen, dat moet een flinke snelheidswinst opleveren. Ik heb versie 5 geinstalleerd en om 't onder de knie te krijgen bakte ik een functie die een bitmap vol met random gekleurde stipjes op 't form zet, als onIdle functie.

Onder Delphi gaat dit lekker snel (dan praat ik over 50 fps, zo op 't oog, bij wijze van spreken) maar onder BCB haal ik amper 2 fps. Eerst maar even de code:

In Delphi 6:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
procedure TForm1.DrawNoise;
var
  x, y: integer;
  ba: PByteArray;
begin
  for y := 0 to bitmap.Height - 1 do
  begin
    ba := bitmap.ScanLine[y];
    for x := 0 to 3 * bitmap.Width - 1 do
      ba[x] := Random(256);
  end;
  Canvas.Draw(0, 0, bitmap);
end;


In C++ Builder 5:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
void TForm1::DrawNoise()
{
        PByteArray ba;
        for(int y = 0; y < bitmap->Height; y++)
        {
                ba = (PByteArray) bitmap->ScanLine[y];
                for(int x = 0; x < 3 * bitmap->Width; x++)
                {
                        ba[x] = random(256);
                }
        }
        Canvas->Draw(0, 0, bitmap);
}

Wat heb ik geprobeerd om het op te lossen? Eerst heb ik de random-functie vervangen door een byte (die steeds groter wordt) om te kijken of de random-functie van BCB misschien gewoon erg traag is. Niet dus. Ik begon te vermoeden dat het aan de debugger lag, maar het uitschakelen van de debug-opties (of simpelweg op de 'release'-knop drukken bij de compiler-opties) hielp ook niets. Toen ben ik aan 't Googlen geslagen met de zoektermen 'borland builder slow debug release', maar dat levert weinig zinvols op; de topics gaan eigenlijk alleen maar over het trage compilen.

Zit ik in de goeie weg te zoeken en zie ik een debug-optie over 't hoofd of moet ik de oorzaak in een hele andere hoek zoeken? Of is dit gewoon de top'snelheid' van BCB? :?

OS: Windows 2000, Professor: XP1800, maarja, die info is eigenlijk overbodig, want onder Delphi gaat het wel lekker snel.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 25-05 22:48

Creepy

Tactical Espionage Splatterer

Bergen schreef op 06 mei 2004 @ 12:03:
Ik werk al sinds jaar en dag in Delphi en omdat ik veel grafische dingetjes maak dacht ik: laat ik C++ Builder eens proberen, dat moet een flinke snelheidswinst opleveren.
Waarom denk je dit? De Delphi compiler van Borland maakt behoorlijk geoptimaliseerde code en doet voor 99% echt niet onder voor de snelheid van een executable gemaakt met een C++ compiler.
Ik heb versie 5 geinstalleerd en om 't onder de knie te krijgen bakte ik een functie die een bitmap vol met random gekleurde stipjes op 't form zet, als onIdle functie.

Onder Delphi gaat dit lekker snel (dan praat ik over 50 fps, zo op 't oog, bij wijze van spreken) maar onder BCB haal ik amper 2 fps. Eerst maar even de code:

In Delphi 6:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
procedure TForm1.DrawNoise;
var
  x, y: integer;
  ba: PByteArray;
begin
  for y := 0 to bitmap.Height - 1 do
  begin
    ba := bitmap.ScanLine[y];
    for x := 0 to 3 * bitmap.Width - 1 do
      ba[x] := Random(256);
  end;
  Canvas.Draw(0, 0, bitmap);
end;


In C++ Builder 5:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
void TForm1::DrawNoise()
{
        PByteArray ba;
        for(int y = 0; y < bitmap->Height; y++)
        {
                ba = (PByteArray) bitmap->ScanLine[y];
                for(int x = 0; x < 3 * bitmap->Width; x++)
                {
                        ba[x] = random(256);
                }
        }
        Canvas->Draw(0, 0, bitmap);
}

Wat heb ik geprobeerd om het op te lossen? Eerst heb ik de random-functie vervangen door een byte (die steeds groter wordt) om te kijken of de random-functie van BCB misschien gewoon erg traag is. Niet dus. Ik begon te vermoeden dat het aan de debugger lag, maar het uitschakelen van de debug-opties (of simpelweg op de 'release'-knop drukken bij de compiler-opties) hielp ook niets. Toen ben ik aan 't Googlen geslagen met de zoektermen 'borland builder slow debug release', maar dat levert weinig zinvols op; de topics gaan eigenlijk alleen maar over het trage compilen.

Zit ik in de goeie weg te zoeken en zie ik een debug-optie over 't hoofd of moet ik de oorzaak in een hele andere hoek zoeken? Of is dit gewoon de top'snelheid' van BCB? :?

OS: Windows 2000, Professor: XP1800, maarja, die info is eigenlijk overbodig, want onder Delphi gaat het wel lekker snel.
Een hele kleine optimalisatie zou kunnen zijn je vars in het begin van de functie te declareren i.p.v. in de for loops. Maar of dit een merkbaar verschil gaat opleveren denk ik niet.

[ Voor 3% gewijzigd door Creepy op 06-05-2004 12:47 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Nee, die variabelen maken geen verschil. Wat wel een verschil kan maken is ( 3*bitmap->Width ) uit de loop halen. Dat zou de optimizer moeten doen, maar handmatig is natuurlijk wel zo leesbaar en betrouwbaar.

Check ook je optimizer opties; de ene release build is de andere niet.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik vermoed dat het verschil zit in de implementatie van random ()

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 16:00
.oisyn schreef op 06 mei 2004 @ 14:02:
Ik vermoed dat het verschil zit in de implementatie van random ()
Wat heb ik geprobeerd om het op te lossen? Eerst heb ik de random-functie vervangen door een byte (die steeds groter wordt) om te kijken of de random-functie van BCB misschien gewoon erg traag is. Niet dus.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Uh ja anders lees ik voortaan even wat beter 8)7

Maar goed, overigens schelen optimalisaties vaak geen factor 25, ik vermoed dat er dus heel anders aan de hand is. Wat je moet gaan doen is je code profilen, zien waar de bottleneck ligt, want nu valt er weinig over te zeggen

Bij gebrek aan een goede profiler kun je natuurlijk ook even zelf afzonderlijke delen timen dmv QueryPerformanceCounter ()

[ Voor 79% gewijzigd door .oisyn op 06-05-2004 14:21 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Je kunt in ieder geval in BCB de resulterende assembler code bekijken (Debug -> View Assembly oid tijdens debug) en in Delphi vermoed ik ook wel. Kijk eens op dat niveau....

Wat een verschil kan zijn is de implementatie van scanline tussen Delphi 6 en BCB 5 (2 verschillende versies van het VCL framework). Als 5 een immediate repaint doet en 6 alleen een invalidate wil ik bijv. factor 25 wel geloven. hum nee ook onzin je tekent op een temp DC.

Waarom zit je trouwens in godesnaam in de onIdle te modderen.... hier is dat ding absoluut niet voor bedoeld en volstrekt onbetrouwbaar. Gebruik gewoon een TTimer op 20ms (is 50fps) en vergelijk het dan eens.

Ik weet niet hoe je je 'framerate' berekent, maar onIdle wordt alleen uitgevoerd zodra de message queue leeg is. Als de message processing snel gaat is de queue dus snel leeg en vang je 1 onIdle voor de hele batch. Dit kan dus feitelijk inhouden dat doordat de C++ code sneller is je onIdle minder wordt aangeroepen en je daardoor een lage framerate ziet!

[ Voor 48% gewijzigd door curry684 op 06-05-2004 14:25 ]

Professionele website nodig?


Verwijderd

Ik weet het niet zeker hoor, maar zou je ook niet ff randomize(); aanroepen?
dan weet je in builder iig dat er een nieuwe random lijst is gemaakt.
Waarom dat het in Delphi niet moet, weet ik niet. Ik ben niet een echte delhi addict.
zie anders ff de borland help inzake random :)

  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 25-05 15:58

Bergen

Spellingscontroleur

Topicstarter
Creepy schreef op 06 mei 2004 @ 12:41:
Waarom denk je dit? De Delphi compiler van Borland maakt behoorlijk geoptimaliseerde code en doet voor 99% echt niet onder voor de snelheid van een executable gemaakt met een C++ compiler.
Euh... in die veronderstelling was ik. :) Ik heb 't dus over applicaties met software rendering e.d., geen databasetoepassing ofzo en ik had begrepen dat dat soort functies in C veel sneller waren.
Een hele kleine optimalisatie zou kunnen zijn je vars in het begin van de functie te declareren i.p.v. in de for loops. Maar of dit een merkbaar verschil gaat opleveren denk ik niet.
Geprobeerd, geen merkbaar verschil.
MSalters schreef op 06 mei 2004 @ 13:30:
Nee, die variabelen maken geen verschil. Wat wel een verschil kan maken is ( 3*bitmap->Width ) uit de loop halen. Dat zou de optimizer moeten doen, maar handmatig is natuurlijk wel zo leesbaar en betrouwbaar.

Check ook je optimizer opties; de ene release build is de andere niet.
Dat eerste leverde ook geen merkbaar verschil op en wat dat tweede betreft: ik heb de volgende opties veranderd: tabblad Compiler->Code optimization op 'Speed', tabblad Advanced Compiler->Floating point op 'Fast'. Verder zou ik niet weten wat de boel sneller kan maken.
.oisyn schreef op 06 mei 2004 @ 14:18:
Bij gebrek aan een goede profiler kun je natuurlijk ook even zelf afzonderlijke delen timen dmv QueryPerformanceCounter ()
Yup, die heb ik onder Delphi ook al es gebruikt, ik denk dat ik die erin ga verwerken.
curry684 schreef op 06 mei 2004 @ 14:21:
Je kunt in ieder geval in BCB de resulterende assembler code bekijken (Debug -> View Assembly oid tijdens debug) en in Delphi vermoed ik ook wel. Kijk eens op dat niveau....
Goed plan, ben benieuwd naar de verschillen.
Waarom zit je trouwens in godesnaam in de onIdle te modderen.... hier is dat ding absoluut niet voor bedoeld en volstrekt onbetrouwbaar. Gebruik gewoon een TTimer op 20ms (is 50fps) en vergelijk het dan eens.
Ja, maar ik wilde even 't maximum opzoeken en met onIdle raast ie dan aan een stuk door. (door Done op False te zetten dus.) Waarom is onIdle onbetrouwbaar btw? :?
Ik weet niet hoe je je 'framerate' berekent, maar onIdle wordt alleen uitgevoerd zodra de message queue leeg is. Als de message processing snel gaat is de queue dus snel leeg en vang je 1 onIdle voor de hele batch. Dit kan dus feitelijk inhouden dat doordat de C++ code sneller is je onIdle minder wordt aangeroepen en je daardoor een lage framerate ziet!
Normaalgesproken wordt onIdle inderdaad 1x aangeroepen, TENZIJ je Done op False zet. ;) De framerate die ik bovenin aangaf was gewoon op 't oog; in Delphi razen de frames voorbij en in C++ haal ik zo'n 2 FPS. Maar ik heb 't even gemeten, gewoon zo dus:
Delphi:
1
2
Inc(FFrames);
Caption := FloatToStr(FFrames * 1000 / (GetTickCount - FStarttime)) + ' FPS';

Delphi met een TTimer heel onverschillig op 1 msec: 61 FPS.
C++ met dezelfde opstelling: 4,4 FPS. (ok ok, iets meer dan 2.. ;))
Verwijderd schreef op 06 mei 2004 @ 16:03:
Ik weet het niet zeker hoor, maar zou je ook niet ff randomize(); aanroepen?
dan weet je in builder iig dat er een nieuwe random lijst is gemaakt.
Wat heb ik aan een verse random-lijst als ik toch alleen maar een scherm vol stipjes maak?
Waarom dat het in Delphi niet moet, weet ik niet. Ik ben niet een echte delhi addict.
zie anders ff de borland help inzake random :)
Delphi kent ook gewoon de randomize-functie. :)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Maar implementeer het nu eens met een timer dan?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1