C# je rychlejší než C/C++?

Jakub Galgonek

Re:C# je rychlejsi ako C/C++?!?!
« Odpověď #15 kdy: 12. 04. 2013, 19:01:07 »
Ale podla mna je spravne porovnavat bez akychkolvek -O, pretoze vtedy kompilator C urobi len nejake vychytraciny (cheatuje :D) zatial co C# to musi vsetko spravit poctivo. Takze zatial za pravoplatne porovnanie povazujem to z mojho prveho prispevku.

To je hloupost, kompilátor C# také jistě provádí optimalizace, takže je dost možné, že ani on ten cyklus vlastně vůbec neprovádí  :)


Re:C# je rychlejsi ako C/C++?!?!
« Odpověď #16 kdy: 12. 04. 2013, 19:08:22 »
Ale podla mna je spravne porovnavat bez akychkolvek -O, pretoze vtedy kompilator C urobi len nejake vychytraciny (cheatuje :D) zatial co C# to musi vsetko spravit poctivo. Takze zatial za pravoplatne porovnanie povazujem to z mojho prveho prispevku.

To je hloupost, kompilátor C# také jistě provádí optimalizace, takže je dost možné, že ani on ten cyklus vlastně vůbec neprovádí  :)
Nicnerobenie by mu urcite netrvalo skoro sekundu. Skusim sa nejako dopracovat aj k skompilovanemu C# kodu a uvidime co robi.

Jakub Galgonek

Re:C# je rychlejsi ako C/C++?!?!
« Odpověď #17 kdy: 12. 04. 2013, 19:13:34 »
Nicnerobenie by mu urcite netrvalo skoro sekundu.

Musí přece nainicializovat tu svou virtuální mašinu, ne?

Můžeš si udělat test. Pokud se ten cyklus opravdu provádí, tak by se doba běhu měla měnit s počtem iterací cyklu (měla by to být přibližně afinní funkce). Co když těch iterací bude 2*999999999?

Re:C# je rychlejsi ako C/C++?!?!
« Odpověď #18 kdy: 12. 04. 2013, 19:18:03 »
Nicnerobenie by mu urcite netrvalo skoro sekundu.

Musí přece nainicializovat tu svou virtuální mašinu, ne?

Můžeš si udělat test. Pokud se ten cyklus opravdu provádí, tak by se doba běhu měla měnit s počtem iterací cyklu (měla by to být přibližně afinní funkce). Co když těch iterací bude 2*999999999?

Ked je iteraci 2x viac tak aj cas behu je priblizne 2x vacsi:

real   0m1.884s
user   0m1.872s
sys   0m0.012s


mimochodom, tu je podstatna cas CIL kodu C# programu (tomu sa uz vobec nerozumiem :D)


   .entrypoint
   // Code size 29 (0x1d)
   .maxstack 3
   .locals init (
      int32   V_0,
      int32   V_1)
   IL_0000:  ldc.i4.0
   IL_0001:  stloc.0
   IL_0002:  ldc.i4.0
   IL_0003:  stloc.1
   IL_0004:  br IL_0011

   IL_0009:  ldloc.0
   IL_000a:  ldc.i4.1
   IL_000b:  add
   IL_000c:  stloc.0
   IL_000d:  ldloc.1
   IL_000e:  ldc.i4.1
   IL_000f:  add
   IL_0010:  stloc.1
   IL_0011:  ldloc.1
   IL_0012:  ldc.i4 999999999
   IL_0017:  blt IL_0009

   IL_001c:  ret
    } // end of method Program::Main

Jakub Galgonek

Re:C# je rychlejsi ako C/C++?!?!
« Odpověď #19 kdy: 12. 04. 2013, 19:35:39 »
mimochodom, tu je podstatna cas CIL kodu C# programu

CIL neznám, ale soudě podle toho řádku s blt ten kód cyklus opravdu provádí. Koukal jsem znovu na výstup z assembleru u C varianty, když není zapnutá optimalizace. Problém je tam ten, že kód provádí ty aritmetické operace s operandy v paměti a ne v registrech - což je časově náročnější. Zapnutí optimalizací však nemůžeš považovat za podvádění, spíše naopak - měl by jsi porovnávat dobu běhu plně optimalizovaného kódu.


Jakub Galgonek

Re:C# je rychlejsi ako C/C++?!?!
« Odpověď #20 kdy: 12. 04. 2013, 19:45:35 »
Schválně si zkus ještě přeložit a pustit tohle:

Kód: [Vybrat]
int main() {
  register int n = 0;
  for (register int i = 0;  i < 999999999;  i++) {
    n++;
  }
}

Re:C# je rychlejsi ako C/C++?!?!
« Odpověď #21 kdy: 12. 04. 2013, 20:03:30 »
Hned mi to pripomnelo http://blogs.msdn.com/b/ricom/archive/2005/05/19/420158.aspx

Jinak porovnavat vysledky 2 RUZNE nastavenych kompilatoru kdy druhy JASNE musi prohrat je ... nefer  ::)
Ten C# by se dal jeste zrychlit ngenem jen tak na okraj.

Re:C# je rychlejsi ako C/C++?!?!
« Odpověď #22 kdy: 12. 04. 2013, 20:16:48 »
Musím se vždycky usmívat, když se znovu a znovu objevují příspěvky, že nějaký kompilátor či dokonce interpretr je rychlejší než C/C++.
C/C++ umožňují pracovat s registry a s přímými přístupy do paměti přes pointery. Nic rychlejšího kromě assembleru už prostě nevymyslíte i kdybyste se rozkrájel :-D. Zapnutí optimalizátoru samozřejmě není žádné cheatování ale regulérní metoda, jejíž možnost a přínosnost je naopak ukazatelem vhodnosti toho či onoho jazyka pro rychlý běh aplikací.

Re:C# je rychlejsi ako C/C++?!?!
« Odpověď #23 kdy: 12. 04. 2013, 20:24:58 »
Schválně si zkus ještě přeložit a pustit tohle:

Kód: [Vybrat]
int main() {
  register int n = 0;
  for (register int i = 0;  i < 999999999;  i++) {
    n++;
  }
}

skusim som a je to o kusticek rychlejsie, stale vsak asi 4x pomalsie

real   0m3.059s
user   0m3.036s
sys   0m0.004s

Re:C# je rychlejsi ako C/C++?!?!
« Odpověď #24 kdy: 12. 04. 2013, 20:27:51 »
Zapnutí optimalizátoru samozřejmě není žádné cheatování ale regulérní metoda, jejíž možnost a přínosnost je naopak ukazatelem vhodnosti toho či onoho jazyka pro rychlý běh aplikací.

Ano, zapnutie optimalizatora v tomto pripade je skutocne cheatovanie, pretoze ucel testu je porovnat KTORY PROGRAM VYKONA DANY CYKLUS RYCHLEJSIE. Kedze optimalizator dany cyklus ODSTRANI, je test uplne na prd. V inom pripade, ked by cyklus mal skutocny zmysel by sa to nedalo takto osalit.
Preto stale za jediny spravny test povazujem test bez optimalizacie, v ktorom je C# 4-5x rychlejsi ako C (aj s pouzitim registrov).

Jakub Galgonek

Re:C# je rychlejsi ako C/C++?!?!
« Odpověď #25 kdy: 12. 04. 2013, 20:29:49 »
C/C++ umožňují pracovat s registry a s přímými přístupy do paměti přes pointery. Nic rychlejšího kromě assembleru už prostě nevymyslíte i kdybyste se rozkrájel :-D. Zapnutí optimalizátoru samozřejmě není žádné cheatování ale regulérní metoda

Jen tak na okraj, čím větší vám jazyk dá svobodu, tím menší prostor má optimalizátor. Třeba potřebujete obsah celočíselné proměnné x a tak si ji načtete do registru. Pak přes ukazatel na double zapíšete někam do paměti. A teď chcete znovu použít proměnnou x. Musí ji překladač nechat znovu načíst z paměti anebo stačí použít hodnotu v registru? Ne, že bych neznal odpověď, ale co myslíte :-)?

Jakub Galgonek

Re:C# je rychlejsi ako C/C++?!?!
« Odpověď #26 kdy: 12. 04. 2013, 20:30:59 »
skusim som a je to o kusticek rychlejsie, stale vsak asi 4x pomalsie

Pořád to neoptimalizuje, jen to už alespoň cpe do registrů.

Jakub Galgonek

Re:C# je rychlejsi ako C/C++?!?!
« Odpověď #27 kdy: 12. 04. 2013, 20:36:26 »
Preto stale za jediny spravny test povazujem test bez optimalizacie, v ktorom je C# 4-5x rychlejsi ako C (aj s pouzitim registrov).

A kde bereš tu jistotu, že ten překladač C# také neoptimalizuje? Ano, vykoná ten cyklus, ale je to bez optimalizace? V podstatě testuješ, který překladač je dostatečně blbý, aby ten cyklus vykonával :). Mimochodem, u gcc se většinou považuje za "normální" překládat s -O2.

OMG

Re:C# je rychlejsi ako C/C++?!?!
« Odpověď #28 kdy: 12. 04. 2013, 21:03:51 »
Musím se vždycky usmívat, když se znovu a znovu objevují příspěvky, že nějaký kompilátor či dokonce interpretr je rychlejší než C/C++.
C/C++ umožňují pracovat s registry a s přímými přístupy do paměti přes pointery. Nic rychlejšího kromě assembleru už prostě nevymyslíte i kdybyste se rozkrájel :-D. Zapnutí optimalizátoru samozřejmě není žádné cheatování ale regulérní metoda, jejíž možnost a přínosnost je naopak ukazatelem vhodnosti toho či onoho jazyka pro rychlý běh aplikací.

Musím se vždycky usmívat, jak mají někteří lidé zafixováno, že nejrychlejší je assembler a C je skoro tak rychlé jako assembler a všechno ostatní je pomalejší.
A když to platí, tak to přece musí platit i u tak malého kousíčku kódu, jako je jeden for cyklus.

Pokud máme program který je celý tvořen pouze for cyklem ve kterém je pouhá jedna inkrementace celočíselné proměnné, tak neporovnáváte rychlost jazyka jako takového, ale porovnáváte pouze kompilátory a jejich nastavení. U takovéhoto kódu prostě záleží, jestli tam ty kompilátory nechají cyklus. Pokud by ho tam nechaly - pak je docela možné, že GCC i CLR JIT kompilátor vyplivnou stejné instrukce - a pokud pomineme CLR režii, tak budou oba programy limitně stejně rychlé.
A je jasné, že v reálném světě u reálných dlouhých cyklů asi nebude mít kompilátor možnost je vyhodit a nahradit pouhým přiřazením proměnné.

Anebo se bude optimalizovat protože to v daném případě půjde. Což CLR dělá zřejmě automaticky (osobně nevím jak moc optimalizuje Mono CLR) a u GCC je to potřeba holt zapnout flagem.


Tipuji, že kdybych založil vlákno "C/C++ je rychlejsi ako C/C++" a rozebíralo se tam rozdíl rychlosti kódů (běžícíh pod windows) zkompilovaného
-na C/C++ kompilátoru od intelu a
-na C/C++ kompilátoru od microsoftu,
že by ty časové rozdíly (a hraní s parametry) byly dost podobné :-D


gamer

Re:C# je rychlejsi ako C/C++?!?!
« Odpověď #29 kdy: 12. 04. 2013, 21:50:28 »
Třeba potřebujete obsah celočíselné proměnné x a tak si ji načtete do registru. Pak přes ukazatel na double zapíšete někam do paměti. A teď chcete znovu použít proměnnou x. Musí ji překladač nechat znovu načíst z paměti anebo stačí použít hodnotu v registru?
Tohle odporuje strict aliasing rules a gcc -O2 optimalizuje na strict aliasing. Naštěstí je gcc takovou prasárnu schopno poznat a (většinou) řekne warning.