Blog IT, Blog Marketing

Szybkość Rusta i C

Szybkość Rusta i C

Marcin Sarna , 15.03.2021 r.

Teoria a praktyka

Szybkość działania i wykorzystanie pamięci przez programy napisane w Rust powinny być mniej więcej takie same, jak w przypadku programów napisanych w C a ogólny styl programowania w tych językach jest na tyle inny, że trudno jest wypowiedzieć się ogólnie o ich szybkości. Istnieje na pewno znacząca różnica między tym, co te języki mogą osiągnąć w teorii, a tym, jak są używane w praktyce.

Generalnie rzecz biorąc:

  • Abstrakcje Rusta to miecz obosieczny. Mogą one ukrywać nieoptymalnie napisany kod ale także ułatwiać wprowadzanie ulepszeń algorytmicznych i korzystać z wysoce zoptymalizowanych bibliotek.
  • Z Rustem raczej nie trafisz w ślepy zaułek - zawsze istnieje jakąś droga wyjścia, która umożliwia optymalizację na bardzo niskim poziomie (i na dodatek nie musisz po to sięgać zbyt często).
  • Gdybyś mógł spędzić nieskończoną ilość czasu i wysiłku, Twoje programy w C byłyby tak szybkie lub nawet szybsze niż Rust, ponieważ teoretycznie nie ma niczego, czego C nie może zrobić tak, jak Rust. Ale w praktyce C ma mniej abstrakcji, prymitywną bibliotekę standardową oraz okropną zarządzanie zależnościami. Po prostu szkoda czasu aby odkrywać koło za każdym razem od nowa.

Oba są „przenośnymi asemblerami”

Zarówno Rust, jak i C dają kontrolę nad układem struktur danych, rozmiarami liczb całkowitych, alokacją pamięci, pośrednimi wskaźnikami i generalnie przekładają się na zrozumiały kod maszynowy z niewielką ilością „magii” wstawianej przez kompilator.

Mimo że Rust ma konstrukcje wyższego poziomu, takie jak iteratory czy inteligentne wskaźniki, są one zaprojektowane w celu przewidywalnej optymalizacji do prostego kodu maszynowego (tak zwane „abstrakcje o zerowym koszcie”). Układ pamięci typów Rusta jest prosty. Rust nie ma żadnej koncepcji takiej jak konstruktory przenoszenia lub kopiowania, więc przekazywanie obiektów nie jest skomplikowane i ogranicza się do przekazywania wskaźnika lub memcpy.

Podatność na tuning

Oba języki pozwalają też na ręczne dostrojenie – co przez to rozumiemy? Rust obsługuje wewnętrzne funkcje SIMD, ma dobrą kontrolę nad wstawianiem, konwencjami wywoływania itp. Rust jest też na tyle podobny do C, że profilery w C zwykle współpracują z Rustem bez konieczności jakiegokolwiek dostosowywania ich (np. można używać Xcode's Instruments w programie złożonych niczym kanapka z Rust, C i Swifta).

Ogólnie rzecz biorąc, gdy wydajność jest absolutnie krytyczna i musi być ręcznie zoptymalizowana do ostatniego bitu, optymalizacja Rusta nie różni się zbytnio od C. Warto zauważyć, że Rust obsługuje obecnie tylko jedną architekturę 16-bitową.

Sprawdź oferty pracy na TeamQuest

Jednak tam, gdzie Rusta nie dostroisz „ręcznie”, mogą pojawić się pewne niedogodności, na przykład:

  1. Brak niejawnej konwersji typów i indeksowania przez Rusta.
  2. Idiomatyczny Rust zawsze przekazuje wskaźnik i rozmiar dla łańcuchów – wiele funkcji C pobiera tylko wskaźnik do pamięci, bez rozmiaru.
  3. Nie wszystkie sprawdzenia granic są zoptymalizowane.
  4. Dla Rusta programy jednowątkowe po prostu nie istnieją jako pojęcie.

Co jeszcze?

Rust wymusza bezpieczeństwo wątków w całym kodzie i danych, nawet w bibliotekach innych firm, nawet jeśli autorzy tego kodu nie zwracali uwagi na bezpieczeństwo wątków. To dramatycznie inna sytuacja niż C. Zwykle żadnemu funkcjom biblioteki nie można ufać, że są bezpieczne dla wątków, chyba że wyraźnie udokumentowano, że jest inaczej. Wielowątkowy kod C niesie ze sobą dużo większą odpowiedzialność.

Rust gwarantuje wolność od „wyścigów danych” (rodzaju współbieżności) i braku bezpieczeństwa pamięci. Istnieje interesująca różnica w sposobie, w jaki biblioteki Rust i C dokumentują bezpieczeństwo wątków. Rust ma słownictwo dotyczące określonych aspektów bezpieczeństwa wątków (Send and Sync, guards czy cells). W języku C nie ma słowa oznaczającego „można go przydzielić w jednym wątku i zwolnić w innym wątku, ale nie można go używać z dwóch wątków jednocześnie”.

Zamiast podsumowania

Rust jest na tyle niskopoziomowy, że w razie potrzeby można go zoptymalizować pod kątem maksymalnej wydajności tak samo dobrze jak C. Abstrakcje, łatwe zarządzanie pamięcią i duża liczba dostępnych bibliotek sprawiają, że programy w Rust mają więcej kodu, robią więcej ale mogą też spuchnąć do naprawdę sporych rozmiarów. Jednak programy w Rust mają też tą cechę, że optymalizują się całkiem dobrze, czasami lepiej niż C. Podczas gdy C jest dobry do pisania minimalnego kodu, Rust ma potężne możliwości jeśli chodzi o efektywne łączenie wielu funkcji, a nawet całych bibliotek w jedną działającą całość.

Najnowsze oferty pracy:

Polecane wpisy na blogu IT:

Szukasz pracownika IT?

Dostarczymy Ci najlepszych specjalistów z branży IT. Wyślij zapytanie

Wyrażam zgodę TeamQuest Sp. z o.o. na przetwarzanie moich danych osobowych w celu marketingu produktów i usług własnych TeamQuest, w tym na kontaktowanie się ze mną w formie połączenia telefonicznego lub środkami elektronicznymi.
Administratorem podanych przez Ciebie danych osobowych jest TeamQuest Sp. z o.o., z siedzibą w Warszawie (00-814), ul. Miedziana 3a/21, zwana dalej „Administratorem".
Jeśli masz jakiekolwiek pytania odnośnie przetwarzania przez nas Twoich danych, skontaktuj się z naszym Inspektorem Ochrony Danych (IOD). Do Twojej dyspozycji jest pod adresem e-mail: office@teamquest.pl.
W jakim celu i na jakiej podstawie będziemy wykorzystywać Twoje dane? Dowiedz się więcej