Java vs C# - benchmark Sudoku

0

Witam,

Od jakiegoś czasu byłem ciekaw porównania** Javy** i C# ale na systemie Windows. Wczoraj przeprowadziłem mały test na Sudoku.
Do testów użyłem kodu ze strony:
https://github.com/attractivechaos/plb/tree/master/sudoku
Kod przerobiłem ten sposób aby programy nie wczytywały danych z pliku - dane umieściłem w programie w tablicach(rozmiar 400 - tyle wersji sudoku do rozwiązania).
Każdy program uruchomiłem klika razy a do mierzenia czasu użyłem programu ptime:
http://www.pc-tools.net/win32/ptime/

Dane wynikowe - na korzyść Javy:
C#: 1.355, 1.309, 1.307 1.310
Java: 0.731, 0,727, 0,721, 0.702

PS.
Programy uruchamiałem przez konsolę Windows7
uruchamianie Java: ptime java Sudoku_v1
uruchamienie C#: ptime sudoku_v1
Jak ktoś chciałby sobie przetestować to na swoim kompie proszę sobie pobrać to:
http://www.speedyshare.com/Vfd44/benchm-jav-Cs.7z

0

.NET 4 / Java 1.7

x86:
.net 0.690 s (csc /o /platform:x86)
java 0.594 s (javac)

x64:
.net 0.448 s (csc /o /platform:x64)
java 0.406 s

i5-2500k @ 4GHz

0

Zainstalowałem cygwina do windowsa i przetestowałem:

Java: 0.701,0.701,0.714,0,720,0.702
Przykład:
real 0m0.702s
user 0m0.015s
sys 0m0.000s

C#: 0,901ms , 0,841ms , 0,849ms, 0,829ms
Przykład:
real 0m0.869s
user 0m0.015s
sys 0m0.016s

0

Nie jestem przekonany do poprawności tych testów. Tzn. ok, fajnie że ktoś zrobił jakieś testy, ale chyba nie wziąłeś pod uwagę sposobu działania tych języków. W C# kod jest początkowo w postaci pośredniej i w chwili wejścia do jakiegoś bloku programu (np. funkcji) jest on kompilowany do kodu natywnego zoptymalizowanego pod konkretną maszynę. W Javie kod jest kompilowany do natywnego dopiero, gdy maszyna wirtualna wykryje, że dany kawałek kodu jest wykonywany często, czyli będzie to opłacalne.

Niech mnie ktoś poprawi, jeśli się mylę (nie jestem pewien co do aktualności tych danych i prawdziwości).

0

Przed chwilą robiłem test czasu w kodzie programu:
Java: 607ms,588ms,590ms,588ms...
C#: 739,67ms, 788,0061ms, 787,033ms

W C# mierzyłem tak:

 
 Stopwatch sw = new Stopwatch();
 sw.Start();
 for (int i = 0; i < table.Length; i++)
 {
    a.solve(table[i]);
 }
 sw.Stop();
 string ExecutionTimeTaken = string.Format("Miliseconds :{0}", sw.Elapsed.TotalMilliseconds);
 Console.WriteLine(ExecutionTimeTaken);

//Microsoft (R) Visual C# Compiler version 4.0.30319.17929
for Microsoft (R) .NET Framework 4.5//

A w Java tak:

 
long start = System.currentTimeMillis();
for( int i = 0; i < table.length;i++)
{
    a.solve(table[i]);
}
long end = System.currentTimeMillis();
System.out.println("Execution time was "+(end-start)+" ms.");

//"java version "1.7.0_03"
Java(TM) SE Runtime Environment (build 1.7.0_03-b05)
Java HotSpot(TM) 64-Bit Server VM (build 22.1-b02, mixed mode)"//

1

Tzn. ok, fajnie że ktoś zrobił jakieś testy, ale chyba nie wziąłeś pod uwagę sposobu działania tych języków.

Gdyby nie było różnic w działaniu, to by nie było różnic w czasie wykonania.
Jak najbardziej ma sens robienie takich pomiarów.

0

Co robi flaga /optimize w csc? Nie wyrzuca przypadkiem jakichś informacji?

Co do Javy 32-bitowej, to można dorzucić opcję -server. W 64-bitowej wersji jest tylko serwerowy HotSpot, więc dopisywanie -server lub -client nic nie zmienia.

0

@Wibowit:

Masz rację - dodanie flagi **optymize **poprawiło wyniki C#:

Java: 607ms,588ms,590ms,588ms...
C#: 739,67ms, 788,0061ms, 787,033ms

Wcześniej kompilowałem w trybie Release bo myślałem że w tym trybie kod jest optymalizowany ale jednak nie jest...

2
Ieoia napisał(a)

Chodzi mi o fakt kompilacji do kodu natywnego. Jeśli mnie pamięć nie myli, to w C# następuje ona tuż przed wykonaniem kodu, co przy niewielkich czasach wykonania może mieć znaczenie.
.NET Framework ma takie narzędzie NGEN. Kompiluje ono kod pośredni do postaci wykonywalnej, tak żeby nie było już potrzeby kompilacji podczas uruchomienia programu.
Wydaje się jednak, że to jest za mały przykład żeby miało to wpływ, bo jak testowałem to nie było żadnych mierzalnych skutów (a jeśli jakieś, to wręcz negatywne).

0

Dziwne jest to że w VS 2012 przy ustawionym trybie Release program działa o wiele dłużej niż program kompilowany ręcznie z flaga /Optimize.
Sprawdzałem w ustawieniach VS projektu i jest zaznaczone "Optymize Code" dla Release.

Sprawdziłem to i co się okazało....
C# VS 2012:
Debug: 3271,7224ms
Release: 1256,868ms
Kompilacja ręczna z flagą /Optimize: 782,9445ms

Dzieje się tak prawdopodobnie dlatego że flaga /Optimize sprawia ze kod jest optymalizowany również w trakcie wykonywania programu. Tak czy siak Java jest szybsza...

0

Mała ciekawostka - zainteresowałem się tym dlaczego w trybie Release programy są wolniejsze od tych kompilowanych ręcznie z opcją /Optymize.
Założyłem nawet topic na msdn: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/5416a784-f1c1-482c-85c1-ecbe90e0e1ad

Co się okazało - okazało się że jak kompiluję ręcznie to programy są kompilowane domyślnie do 64-bit a jak kompiluję w VS to domyślnie są kompilowane do 32-bitów(Opcja "Prefer 32-bit"). Tak więc jak chcecie mieć szybsze programy to odznaczcie "Prefer 32-bit" w opcjach projektu VS.

Różnica jest wielka: 1256,868ms - 782,9445ms

0

Nie wiem co tu w ogóle porównywać. Każdy przecież wie ,że cała platforma .NET jest do bani. Sam C# jest dobrze zaprojektowanym językiem ale jak już mówiłem ,ale cały .NET to syf. Java rządzi!

1 użytkowników online, w tym zalogowanych: 0, gości: 1