2009-09-15 12 views
5

(To miało być ogólne pytanie hipotetyczne, mnie marudzenie, że .NET był świnią i prosząc o powodów. To nie było naprawdę ma być pytanie o mojej konkretnej aplikacji.)Dlaczego .NET używa tak dużo procesora, czy to jest problem?

Obecnie jestem przepisanie starego kodu C++ w języku C#. Przenosimy port do wszystkich starszych aplikacji. Mam aplikacje C++, które pobierają MAX 3% CPU. Przeważnie nie używają żadnego. Następnie wziąłem kod, skopiowałem i wkleiłem, a następnie ponownie sformatowałem do składni C# i bibliotek .NET oraz BAM! 50% procesora. Jaki jest tego powód? Początkowo myślałem, że to JIT, ale nawet po tym, jak każda ścieżka kodowa była ćwiczeniem, a cała sprawa była JIT ed, ten sam problem.

Zauważyłem również ogromny wzrost pamięci. Aplikacje, które zajęły 9 MB z pełnym obciążeniem, zaczynają teraz od 10 MB i działają z szybkością 50 MB. Rozumiem, że sprzęt jest tani, ale chcę zrozumieć, co to powoduje. Czy to jest powód do niepokoju, czy też .NET to tyle świni?

Update 1 Odpowiedź do rzutków

znam C#. Zmieniam rzeczy na Linq i tak dalej. Zazwyczaj biorę kod i zmniejszam liczbę linii i tak dalej. Czy mógłbyś podać kilka przykładów tego, co osoba C++ robi źle w .NET?

Aktualizacja 2

To miało być ogólne pytanie, ale specyficzna aplikacja, która ma ten problem jest następujący.

Posiada wątek, który używa sterownika ODBC i pobiera dane z paradoksu db. Następnie używa Linq do przekształcenia tego w SQL db i opublikowania go. Uruchomiłem to przez profiler ANTS i wydaje się, że wypełnianie zestawu danych zabiera najwięcej czasu. Następuje wysłanie Linq. Wiem, że niektóre z moich dziedzin są używane w odbiciu, ale nie widzę, jak zrobić to, czego potrzebuję bez tego. Mam zamiar zmienić mój ciąg na konstruktorów ciągów. Czy jest jakaś różnica między tymi dwoma?

(int)datarow["Index"] 

i

ConvertTo.Int32(datarow["Index"]) 

zmieniłem wszystkie konkatenacji ciągów do ciągów wielkoformatowych. To nie zmniejszyło się ponad głowę. Czy ktokolwiek zna różnicę między czytnikiem danych a adapterem danych i zestawami danych?

+9

Zamiast potrzebować teoretycznych przykładów, lepiej użyć profilera, aby sprawdzić, dlaczego Twoja aplikacja wydaje CPU. – ChrisW

+1

Wygląda na to, że może to być interakcja z ODBC. Czy dostępny jest "macierzysty" sterownik .NET Paradox? –

+3

50% procesora na jak długo? Do jakiego zadania? W intensywnych procesorowych mini-benchmarkach, które studiowałem, C++ był szybszy niż C#, ale nie za dużo. W każdym przypadku przesycałem procesor w celu uzyskania najwyższej przepustowości. – Cheeso

Odpowiedz

17

Jak dobrze znasz C# i .NET? Jeśli po prostu przenosisz się nad starszym kodem zachowującym idiomy C++, wcale się nie dziwię, że to bycie wieprzem. Przenoszenie aplikacji dosłownie z jednej platformy na drugą prawie nigdy nie jest dobrym pomysłem. (Oczywiście, nie powiedziałeś, że na pewno to zrobiłeś.) Ponadto, jeśli jesteś ekspertem od programowania w C++, ale początkującymi programistami .NET, powinieneś oczekiwać, że Twój kod wykona tak, jakbyś był nowicjuszem Platforma.

Nie możemy naprawdę powiedzieć, co robi przedstawienie, nie wiedząc nic więcej o aplikacji - chociaż nie zdziwiłbym się, że winowajcą była ta konkatenacja ciągów znaków. Ile procesorów masz na pudełku? Jeśli jest to 2, to aplikacja bierze wszystko, co tylko możliwe dla pojedynczego wątku ...

.NET będzie generalnie cięższy pod względem pamięci niż aplikacja C++, ale powinien mieć co najmniej porównywalny pod względem prędkości dla większości zadań. Zażywanie 50MB zamiast 9MB brzmi bardziej, niż się spodziewałam, ale nie byłbym zbytnio martwy zbyt.

Zarówno pamięć, jak i wydajność procesora powinny być sprawdzone za pomocą dobrego profilera. Mogę polecić JetBrains dotTrace Profiler, ale jest tam wiele innych.

+0

Czy możesz podać więcej przykładów? –

+0

Coś, co może być nowicjuszem .NET, co może zrobić facet C++? –

+3

Przykłady czego? Nie wiedząc nic o swojej aplikacji, trudno byłoby odgadnąć, gdzie mogą występować wąskie gardła. Nawet samo użycie LINQ może doprowadzić do wąskiego gardła, jeśli nie będziesz ostrożny. Naprawdę wybrałbym profilera - wszystko inne będzie po prostu zgadywaniem. –

0

Powiedziałbym, że użycie pamięci jest prawdopodobnie w linii, ale użycie procesora nie jest.

Wygląda na to, że masz wątek, który nie ustępuje.

1

Powinieneś zobaczyć wzrost wykorzystania procesora. 3% do 50% brzmi jak za dużo, jaki to kod?

Ślad pamięci to nieunikniony koszt. Każda rzecz między 30-50 MB dla aplikacji .NET jest normalna. Zwykle rzeczywiste wykorzystanie pamięci przez aplikację .NET jest bardzo małe, ale istnieje spore obciążenie dla środowiska wykonawczego, którego nie można uniknąć (jest to jednorazowy koszt, ale istnieje) i jest bardzo zauważalne, jeśli odwołujesz się do ton zestawów .

0

mogę wymyślić kilka hipotez:

1) Pamięć - C++ nie udało pamięć. W ten sposób uwalnia on pamięć stopniowo i przy (jeśli jest odpowiednio zaprogramowany) optymalnym czasie.

Z pamięcią zarządzaną program zasadniczo "przecieka" pamięć do czasu, w którym zdecyduje się na wykonanie koagulacji śmieci. Czas jest prawdopodobnie zależny od ilości pamięci przydzielonej do procesu. Prawdopodobnie istnieje sposób zmiany domyślnego zachowania, ale mniejszy rozmiar pamięci oznacza, że ​​kolekcja zbierania śmieci ma miejsce wcześniej i częściej, co wpływa na czas przetwarzania. Jeśli zostanie przydzielona wystarczająca ilość pamięci, to gc może nie wymagać inv9ked.

2) Czy program działa w tym samym czasie lub mniej? Jeśli zużywa 5 razy więcej mocy procesora, ale kończy o 1/5 czasu, wtedy używany procesor jest w zasadzie równoważny.

3) Tak, .NET jest prawdopodobnie świnia

+1

Jeśli dzwonisz .Net świnia, twoje imię jest bardzo właściwe –

+0

Nie rozumiem :) Osobiście nie widzę nic złego w byciu "świnią" w dzisiejszych czasach. Podoba mi się VB .NET, to najlepsze środowisko programistyczne W międzyczasie miałem interlip w późnych latach 80-tych, i jest wspierane przez ramy, które mogą być wykorzystywane do dostarczania komercyjnych aplikacji zamiast tylko fajnych pokazów/badań/dowodów koncepcji. Wydaje mi się, że główną lekcją Javy było "teraz być świnią ... mamy wystarczającą moc obliczeniową", którą Microsoft wziął sobie do serca i ponownie zaimplementował, w mojej głowie, w znacznie lepszy sposób (lepszy IDE, lepiej wydajniejszy wygenerowany kod). To świnia, ale bardzo SZYBKA świnia :) –

6

AFAIK jest Litte różnica między (int)datarow["Index"] i ConvertTo.Int32(datarow["Index"]). Jednak istnieje duża różnica jeśli używasz strumieniowych czytniki danych Tryb:

int orderIndex = <order of Index column in projection list>; 
using (OdbcDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) 
{ 
    int Index = rdr.GetInt32(orderIndex); 
} 

SeqentialAccess zachowanie polecenia jest fastes sposób przetwarzać SQL wyników, gdyż nie eliminuje dodatkowe buforowanie potrzebne do losowego dostępu.

Druga informacja to taka, że ​​wygląda na to, że używasz zestawów danych. Zestawy danych są łatwe w użyciu, ale są bardzo dalekie od tego, co każdy może nazwać "szybkim". W przypadku zestawów danych zasadniczo działasz w silniku pamięciowym (myślę, że jest oparty na Rushmore). Jeśli chcesz wycisnąć każdy cykl procesora i wszystkie 1s z każdego bitu RAM, będziesz musiał użyć komponentów szczuplejszych (np. Surowe tablice struktur zamiast Datasets i DataTables).

Porównując jabłka do jabłek, CLR może być odporny na kod natywny. Kod IL może być ukryty w czasie wdrażania z NGEN. Typowe narzuty CLR, takie jak bounds checks can be avoided. Zastrzeżenie GC "pauza" dzieje się tylko wtedy, gdy jesteś nieostrożny przy przydzielaniu (tylko dlatego, że masz GC, nie oznacza, że ​​powinieneś zająć lewe i prawe). A CLR ma kilka asów, jeśli chodzi o układ pamięci, ponieważ może zamienić obiekt w pamięć, aby dopasować wzorce dostępu i poprawić lokalizację TLB i L2.

BTW, jeśli uważasz, że debatę „C++ mogą okrążać C#” jest czymś nowym, pamiętam czasy, kiedy C może uruchomić kręgi wokół C++ („Połączenia wirtualne są niemożliwie wolno” mówią) i słyszę tam był zbiorem czasu, który kręcił się wokół C.

Powiązane problemy