W C # jest opcja wykonania niezaznaczonego kodu. Zasadniczo nie jest to zalecane, ponieważ zarządzany kod jest znacznie bezpieczniejszy i pozwala przezwyciężyć wiele problemów.
Zastanawiam się jednak, jeśli masz pewność, że Twój kod nie spowoduje błędów, a wiesz, jak obsługiwać pamięć, to dlaczego (jeśli lubisz szybki kod) postępować zgodnie z ogólną radą?
Zastanawiam się nad tym, ponieważ napisałem program do kamery wideo, który wymagał bardzo szybkiej manipulacji bitmapą. Sam stworzyłem szybkie algorytmy graficzne, które doskonale działają na mapach bitowych przy użyciu niezarządzanego kodu.
Teraz ogólnie zastanawiam się, czy jeśli jesteś pewien, że nie masz wycieków pamięci lub ryzyka awarii, dlaczego nie częściej używać niezarządzanego kodu?
PS moje tło: W pewnym sensie wkroczyłem w ten świat programowania i pracuję sam (robię to przez kilka lat), więc mam nadzieję, że to pytanie dotyczące projektowania oprogramowania nie jest takie dziwne. Naprawdę nie mam innych ludzi takich jak nauczyciel, którzy mogliby zadawać takie pytania.
źródło
unsafe
oznacza „wiedzieć, co robisz, i porównać korzyści z ryzykiem”. Użyłemunsafe
kilka razy i zawsze dotyczyło to czegoś bardzo specyficznego związanego z wydajnością, które można odgrodzić własną metodą. Nie używam go jako ogólnej techniki programowania, ponieważ przez większość czasu dodatkowa korzyść z wydajności nie jest warta utraty bezpieczeństwa.unsafe
przykład użycia: stackoverflow.com/q/11660127/102937Odpowiedzi:
Cóż, w większości przypadków jest to powiedzenie stare
Ale tak naprawdę mogę wymyślić trzy główne powody, dla których należy unikać niebezpiecznego kodu.
Błędy : krytyczna część pytania brzmi: „jeśli masz pewność, że kod nie spowoduje błędów”. Jak możesz być absolutnie pewien? Czy używałeś metody z formalnością, która gwarantowała poprawność kodu? Jedno jest pewne w programowaniu, a mianowicie, że będziesz mieć błędy. Kiedy zdejmujesz bezpieczeństwo, pozwalasz, aby nowe rodzaje błędów przenikały. Kiedy pozwalasz, aby śmieciarz zajął się twoją pamięcią, wiele problemów zniknie.
Nie zawsze tak szybko, jak myślisz : Inną kwestią jest: w zależności od problemu zysk może nie być tak duży. Chociaż wydaje się, że nie mogę ich teraz znaleźć, pamiętam badanie przeprowadzone przez Google porównujące szybkość Java, Scala, Go i C ++. Po zoptymalizowaniu pod kątem ziemi C ++ był oczywiście znacznie szybszy. Ale algorytm zaprogramowany w sposób „idiomatyczny” nie był tak naprawdę szybszy. Idiomatyczny w tym sensie, że używali standardowej struktury i idiomów (kontener stl, brak rozwiniętej pętli itp.). Microsoft przeprowadził podobny eksperyment z C # i C ++. Raymond Chen, jeden z najlepszych inżynierów Microsoft, musiał napisać własną implementację std :: string, aby pokonać C #. (patrz: http://www.codinghorror.com/blog/2005/05/on-managed-code-performance-again.html) Przy znacznie mniejszym wysiłku uzyskano całkiem przyzwoitą wydajność w kodzie zarządzanym, więc często nie jest to warte kłopotu.
Wielokrotnego użytku : Niebezpieczny kod może być używany tylko w środowisku pełnego zaufania. Na przykład na serwerze ASP.NET zwykle nie można użyć niebezpiecznego kodu, ponieważ wprowadzenie luki w zabezpieczeniach przez przepełnienie bufora byłoby dość łatwe. Innym przykładem może być clickonce. Lub jeśli twoja aplikacja była dostępna z udziału sieciowego. Jeśli więc planujesz używać swojego kodu w różnych scenariuszach wdrażania, niebezpieczny kod nie wchodzi w grę.
Więc w zasadzie: jest to niezadowolone, ponieważ może wprowadzać niepotrzebne błędy, może w ogóle nie przynosić korzyści i zmniejsza przydatność twojego kodu do ponownego użycia.
Ale jeśli twój scenariusz naprawdę wymaga wydajności (i masz dane, aby to udowodnić), jesteś doświadczonym programistą, który wie, jak obsługiwać pamięć, a twój kod będzie używany w kontrolowanym środowisku, więc na pewno, idź.
źródło
W pewnym sensie niezarządzany kod jest formą płatności: kupujesz szybsze wykonanie przy dodatkowym wysiłku programistycznym. Rzeczywiście, niezarządzany kod wymaga więcej czasu na opracowanie, debugowanie i utrzymanie. Prawidłowe zrobienie tego jest wyzwaniem dla większości uczestników. W pewnym sensie jest to podobne do programowania w asemblerze: na pewno możesz wycisnąć więcej mocy z procesora, jeśli piszesz w asemblerze * , ale „spędzasz” dużo więcej wysiłku, idąc tą drogą.
Czasami różnica w czasie programowania jest bardzo znacząca - dni zamiast godzin. Różnica w szybkości wykonywania nie jest jednak aż tak dramatyczna. Dlatego rozwój niezarządzanego kodu jest zarezerwowany dla sytuacji podobnych do opisanej w poście - zlokalizowanych, niezależnych implementacji algorytmów wymagających zasobów, takich jak przetwarzanie audio i wideo.
Zasadniczo odpowiedź na twoje pytanie jest podobna do odpowiedzi, dlaczego nie wszyscy jeżdżą Ferrari: to znacznie lepszy samochód, prawda? (Nie) na szczęście nie wszyscy mogą sobie na to pozwolić.
* Postępy ostatnich dziesięcioleci w technologii optymalizacji w kompilatorach tak bardzo zmniejszyły tę lukę, że nie jest to już pewny zakład.
źródło
Ponieważ bycie „pewnym” co do poprawności lub jakiegokolwiek innego ograniczenia w sensie matematycznym (tj. Masz dowód) jest bardzo trudnym problemem dla języków imperatywnych. Programy często mają tak dużą liczbę stanów, że nie można ich zweryfikować nawet po sprawdzeniu każdego możliwego stanu. Tworzenie konstruktywnego dowodu nie jest czymś, co można zautomatyzować.
Powodem jest to, że ubezpieczenia, które zarządza wykonaniem, najczęściej przeważają niewielki wzrost wydajności, który można uzyskać przy użyciu niebezpiecznego kodu. Oczywiście zależy to również od konkretnego przypadku użycia.
źródło
Krótko mówiąc, nic nie stoi na przeszkodzie, abyś wykonał całą tę pracę i zarządzał bitami programu w środowisku C ++. Ponieważ jesteś pewien, że możesz poprawnie zarządzać wszystkimi obręczami pamięci i przeciekami bez modułu wyrzucania elementów bezużytecznych, możesz to zrobić w C ++ :)
Przeciwnie, C # ma zalety zapewniające bezpieczne / zarządzane i silnie typowane środowisko programistyczne do bezpiecznego działania w środowisku .NET.
Możliwym przesunięciem wstecznym programowania niezarządzanego kodu jest dłuższy czas programowania, alokacja czasu na szczegółowe testowanie. Zyskasz oczywiście szybkość przetwarzania i większą kontrolę nad sposobem działania oprogramowania.
Tak więc opcja pracy z niezarządzanym kodem w .NET Framework od wersji 4.0 jest opcją dla przypadków skrajnych, gdy masz pewność, że może to przynieść korzyści w stosunku do nieużywania go.
źródło