Jestem programistą C ++ i C #. Tworzyłem aplikacje C # od pierwszej wersji beta frameworka .NET i mam ponad 20 lat doświadczenia w tworzeniu aplikacji C ++. Po pierwsze, kod C # NIGDY nie będzie szybszy niż aplikacja w C ++, ale nie będę przechodził długiej dyskusji na temat zarządzanego kodu, jego działania, warstwy międzyoperacyjnej, wewnętrznych elementów zarządzania pamięcią, dynamicznego systemu typów i garbage collectora. Niemniej jednak pozwolę sobie kontynuować, mówiąc, że wszystkie wymienione tutaj testy porównawcze dają NIEPRAWIDŁOWE wyniki.
Pozwól, że wyjaśnię: Pierwszą rzeczą, którą musimy wziąć pod uwagę, jest kompilator JIT dla C # (.NET Framework 4). Teraz JIT tworzy natywny kod dla procesora przy użyciu różnych algorytmów optymalizacji (które są zwykle bardziej agresywne niż domyślny optymalizator C ++ dostarczany z programem Visual Studio), a zestaw instrukcji używany przez kompilator .NET JIT jest bliższym odzwierciedleniem rzeczywistego procesora na maszynie, aby można było wprowadzić pewne podstawienia w kodzie maszynowym, aby zmniejszyć cykle zegara i poprawić współczynnik trafień w pamięci podręcznej potoku procesora oraz uzyskać dalsze optymalizacje hiperwątkowości, takie jak zmiana kolejności instrukcji i ulepszenia dotyczące przewidywania rozgałęzień.
Oznacza to, że jeśli nie skompilujesz aplikacji w języku C ++ przy użyciu poprawnych parametrów dla kompilacji RELEASE (nie kompilacji DEBUG), aplikacja w języku C ++ może działać wolniej niż odpowiadająca jej aplikacja oparta na języku C # lub .NET. Określając właściwości projektu w swojej aplikacji C ++, upewnij się, że włączono „pełną optymalizację” i „preferuj szybki kod”. Jeśli masz maszynę 64-bitową, MUSISZ określić generowanie x64 jako platformy docelowej, w przeciwnym razie kod zostanie wykonany przez podwarstwę konwersji (WOW64), co znacznie zmniejszy wydajność.
Po wykonaniu poprawnych optymalizacji w kompilatorze otrzymuję 0,72 sekundy dla aplikacji C ++ i 1,16 sekundy dla aplikacji C # (obie w kompilacji wydania). Ponieważ aplikacja C # jest bardzo prosta i alokuje pamięć używaną w pętli na stosie, a nie na stercie, w rzeczywistości działa o wiele lepiej niż prawdziwa aplikacja zaangażowana w obiekty, ciężkie obliczenia i większe zestawy danych. Zatem podane liczby są optymistycznymi liczbami ukierunkowanymi na język C # i platformę .NET. Nawet przy takim odchyleniu aplikacja C ++ działa w nieco ponad połowę krótszego czasu niż jej odpowiednik w języku C #. Należy pamiętać, że kompilator Microsoft C ++, którego użyłem, nie miał odpowiedniego potoku i optymalizacji wielowątkowości (użycie WinDBG do przeglądania instrukcji asemblera).
Teraz, jeśli użyjemy kompilatora Intela (który, nawiasem mówiąc, jest tajemnicą branżową, jeśli chodzi o generowanie aplikacji o wysokiej wydajności na procesorach AMD / Intel), ten sam kod jest wykonywany w 0,54 sekundy dla pliku wykonywalnego C ++ w porównaniu z 0,72 sekundy przy użyciu Microsoft Visual Studio 2010 Tak więc ostateczne wyniki to 0,54 sekundy dla C ++ i 1,16 sekundy dla C #. Zatem kod tworzony przez kompilator .NET JIT trwa 214% razy dłużej niż plik wykonywalny C ++. Większość czasu spędzonego w 0,54 sekundy była na pobieraniu czasu z systemu, a nie w samej pętli!
W statystykach brakuje również czasów uruchamiania i czyszczenia, które nie są uwzględnione w chronometrażu. Aplikacje C # spędzają dużo więcej czasu na uruchamianiu i kończeniu pracy niż aplikacje C ++. Przyczyna tego jest skomplikowana i ma związek z procedurami sprawdzania poprawności kodu środowiska uruchomieniowego .NET i podsystemem zarządzania pamięcią, który wykonuje dużo pracy na początku (iw konsekwencji na końcu) programu, aby zoptymalizować alokacje pamięci i śmieci kolektor.
Podczas pomiaru wydajności C ++ i .NET IL ważne jest, aby spojrzeć na kod asemblera, aby upewnić się, że są tam WSZYSTKIE obliczenia. Odkryłem, że bez umieszczania dodatkowego kodu w C #, większość kodu z powyższych przykładów została faktycznie usunięta z pliku binarnego. Tak było również w przypadku C ++, kiedy używałeś bardziej agresywnego optymalizatora, takiego jak ten, który jest dostarczany z kompilatorem Intel C ++. Wyniki, które podałem powyżej są w 100% poprawne i sprawdzone na poziomie montażu.
Głównym problemem z wieloma forami w Internecie jest to, że wielu początkujących słucha propagandy marketingowej firmy Microsoft bez zrozumienia technologii i fałszywie twierdzi, że C # jest szybszy niż C ++. Twierdzi się, że teoretycznie C # jest szybszy niż C ++, ponieważ kompilator JIT może zoptymalizować kod pod kątem procesora. Problem z tą teorią polega na tym, że w środowisku .NET istnieje wiele elementów hydraulicznych, które spowalniają wydajność; hydraulika, która nie istnieje w aplikacji C ++. Ponadto doświadczony programista będzie znał właściwy kompilator do użycia dla danej platformy i użyje odpowiednich flag podczas kompilacji aplikacji. Na platformach Linux lub open source nie stanowi to problemu, ponieważ można dystrybuować źródła i tworzyć skrypty instalacyjne, które kompilują kod przy użyciu odpowiedniej optymalizacji. W systemie Windows lub platformie o zamkniętym kodzie źródłowym będziesz musiał rozpowszechniać wiele plików wykonywalnych, każdy z określonymi optymalizacjami. Pliki binarne systemu Windows, które zostaną wdrożone, są oparte na procesorze wykrytym przez instalator msi (przy użyciu akcji niestandardowych).