Avatar billede Lasse Novice
02. oktober 2007 - 00:44 Der er 13 kommentarer og
1 løsning

C# outperforms vb og c++

Jeg har noget kode som jeg gerne vil portere til VB og c++. Ikke desto mindre finder jeg eksekverings hastigheden i VB og c++ rystende langsom i forhold til c#. Er der nogen der kan forklare om jeg kan optimere mit VB kode... og mit c++ u/pointere kode. Her er tiderne:

1) c#: 0.3 sec
2) c++ u/pointere: 1.4 sec
3) c++ m/pointere: 0.015 sec
4) VB: 25 sec

Koden er som foelger:
1) c#:
int count = 1024 * 3 * 768;

byte[] bs = new byte[count];

DateTime start = DateTime.Now;

for (int h = 0; h < 100; h += 3)
{
  for (int i = 0; i < count - 1; i += 3)
  {
    byte r = bs[i + 2];
    byte g = bs[i + 1];
    byte b = bs[i + 0];

    bs[i + 0] = (byte)(255 - b);
    bs[i + 1] = (byte)(255 - r);
    bs[i + 2] = (byte)(255 - g);
  }
}

DateTime end = DateTime.Now;

MessageBox.Show((end - start).ToString());

2) c++ u/pointere:
int byteWidth = 1024 * 3;
int byteHeight = 768;
int count = byteWidth * byteHeight;

DWORD start = GetTickCount();

char* bs = new char[count];

for(int h = 0; h <100; h++)
{
  for(int i = 0; i < count - 1; i+=3)
  {
    char r = bs[i + 2];
    char g = bs[i + 1];
    char b = bs[i + 0];

    bs[i + 0] = (char)(255 - b);
    bs[i + 1] = (char)(255 - r);
    bs[i + 2] = (char)(255 - g);
  }
}

DWORD end = GetTickCount();

DWORD interval = end - start;

printf ("Width trick: %d \n", interval);

3) c++ m/pointere:
int byteWidth = 1024 * 3;
int byteHeight = 768;
int count = byteWidth * byteHeight;

DWORD end = GetTickCount();

DWORD interval = end - start;

int index = 0;

while(index < count)
{
  char r = *(bs + index + 2);
  char g = *(bs + index + 1);
  char b = *(bs + index + 0);

  *(bs + index + 0) = 255 - b;
  *(bs + index + 1) = 255 - g;
  *(bs + index + 2) = 255 - r;
  index+=3;
}

DWORD end2 = GetTickCount();

DWORD interval2 = end2 - end;

printf ("Width trick: %d \n", interval2);

4) VB:
Dim count As Long
count = 1024 * 3
count = count * 768

Dim bs2() As Byte

ReDim Preserve bs2(count)

Dim r As Byte
Dim g As Byte
Dim b As Byte
Dim lngStart As Long
Dim lngFinish As Long

lngStart = GetTickCount()

For h = 0 To 100
    For i = 0 To count - 1 Step 3
        r = bs2(i + 0)
        g = bs2(i + 1)
        b = bs2(i + 2)
       
        bs2(i + 0) = 255 - r
        bs2(i + 1) = 255 - g
        bs2(i + 2) = 255 - b
    Next
Next

lngFinish = GetTickCount()

MsgBox CStr(lngFinish - lngStart)
Avatar billede arne_v Ekspert
02. oktober 2007 - 00:55 #1
Så vidt jeg kan se laver du 3 gange så mange gennemløb i C++ uden pointere !
Avatar billede arne_v Ekspert
02. oktober 2007 - 00:56 #2
for (int h = 0; h < 100; h += 3)
{
  for (int i = 0; i < count - 1; i += 3)
  {

og

for(int h = 0; h <100; h++) // <----- ikke +3 her
{
  for(int i = 0; i < count - 1; i+=3)
  {
Avatar billede arne_v Ekspert
02. oktober 2007 - 00:58 #3
Og ditto med din VB kode.

Og VB6 kode kan du ikke forvente kan konkurrere med C# og C++ til den slags her.
Avatar billede pidgeot Nybegynder
02. oktober 2007 - 11:59 #4
Derudover kommer at det kun er C# koden der beregner count uden at gå igennem andre variable. Det gør det nemmere for compileren at optimere en smule ved at beregne værdien på forhånd, så det bliver en konstant (dermed ikke sagt at C++ compileren ikke måske kan spotte at det er det der sker, men det kan man jo ikke være sikker på).
Avatar billede arne_v Ekspert
02. oktober 2007 - 16:10 #5
Selvom C++ compileren ikke kan optimere det så er det vel kun et par milliardtedele sekunder det gør i forskel.
Avatar billede Lasse Novice
02. oktober 2007 - 17:10 #6
Ok, jeg kan se at eksemplerne ikke laver helt det samme. Jeg har nu aendret dem alle til det samme:

- loeb et rgb billede igennem 100 gange m. stoerrelsen 1024 * 768
- Alle i release mode

C#: 0.56 sec
c++ u/pointere: 0.4 sec
c++ m/pointere: 0.4 sec
vb: 25 sec

Nu kan jeg bedre lide det... c++ er hurtigere end c#, hvilket jeg mener er paa sin rette plads. Ikke desto mindre ser jeg VB rode nederst, hvilket er aergeligt da jeg hellere vil skrive en ActiveX i VB end i c++.

Arne_v>> svar => point.
Avatar billede pidgeot Nybegynder
02. oktober 2007 - 17:26 #7
Arne: Selvfølgelig - og jeg ved skam også godt at den vil blive udført inden tidstagningen starter - men jeg nævner det primært for at pointere at der er flere forskelle end som så. C# koden bruger heller ikke GetTickCount som de tre andre, men DateTime.Now - den kan faktisk godt gå hen og skabe en forskel, omend det nok mest er i nøjagtigheden af timingen.

Hvis vi skal komme med et reelt optimeringstrick der måske kan spare tid, så var det at bruge bitvis NOT i stedet for at trække 255 fra. Det kan godt være en smule hurtigere, omend det afhænger af om kilde og destination er identisk (endnu et punkt hvor der er lidt uenighed, men hvis det er har du ikke brug for de midlertidige r, g og b-variable), og i så fald om compileren er smart nok til at operere direkte på den placering i hukommelsen, eller om den vil hente ud i en intern variabel.
Avatar billede arne_v Ekspert
02. oktober 2007 - 17:52 #8
Du kan da lave din ActiveX i C# !?!?

Og et svar.
Avatar billede Lasse Novice
02. oktober 2007 - 17:56 #9
ingen problem med activeX i c#, udover 2 ting:

1) microsoft suporterer det ikke
2) Mnage har stadig ikke installeret .NET og det ville vaere aergeligt at miste disse mennesker.
Avatar billede arne_v Ekspert
02. oktober 2007 - 21:54 #10
Jeg mener da at det er muligt.

Hvis du vil nå alle er ActiveX så et godt valg ?

MacOS X og Linux brugerne kan ikke køre ActiveX.

Men der er nok endnu flere Windows brugere som ikke vil tilade ActiveX.
Avatar billede Lasse Novice
03. oktober 2007 - 15:53 #11
Vores hjemmeside target'er windows, mac og linux brugere :-) Vi har lavet en survey paa vores hjemmeside, og lidt under halvdelen havde .net installeret (af dem som kommer fra windows), hvilket gjorde at vi saa bort fra denne mulighed. Bemaerk at vi ikke kun skal bruge activeX'en paa vores hjemmeside, men ogsaa i vores program.

Hvilke muligheder er der ellers?

Jeg kunne forestille mig at idet jeg har en activeX kontrol i c++, saa er det ikke saerlig svaert at lave noget tilsvaerende indenfor MAC verdenen og indenfor linux verdenen...
Avatar billede sherlock Nybegynder
03. oktober 2007 - 15:56 #12
Velkommen til den vidunderlige Java-verden :)
Avatar billede Lasse Novice
03. oktober 2007 - 16:08 #13
Kan man godt indsaette en java... kontrol?/applet? ind i et .net projekt f.eks.?

Og hvordan performer java i forhold til c++, vb og c# mht. byte array operationer?
Avatar billede arne_v Ekspert
03. oktober 2007 - 16:36 #14
Nej - der eksisterer ikke umiddelbart noget der svarer til ActiveX til andre
platforme. ActiveX er en del af COM/OLE/og-hvad-ved-jeg.

Du kan lave plugins til andre browsere, men det er en lidt anden løsning.

Server side er en Java applet et HTML tag der outputtes on en binær fil der serves
af web serveren. Den kan laves i ASP.NET, PHP eller pure HTML.

Du får også et problem med Java idet ikke alle har installeret Java.

Men du kan få Java til alle de nævnte platforme. Og du kan bruge præcis samme
Java applet til dem alle.

Hvis folk har en nyere Java, så burde den performe mere ligesom C++/C# end som VB6.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester