Benchmark rozszerzeń Swift a metody: Swift 4.1 (maj 2018)

Interaktywne wykresy są dostępne tutaj: http://minikin.me/extensions

Ivation Motywacja

Kilka tygodni temu rozmawiałem z programistą iOS, który ma wiele silnych przekonań. Jeden z nich brzmi następująco: „Korzystanie z rozszerzeń Swift jest bardzo złą praktyką, ponieważ czas kompilacji dramatycznie się wydłuża oraz zmniejsza czytelność i przejrzystość kodu”. Nie będę oceniać czytelności i przejrzystości. To są preferencje dotyczące stylu osobistego, ale byłem dość zdezorientowany argumentem dotyczącym czasu kompilacji. Pamiętam, że były dyskusje na ten temat trzy lub więcej lat temu. Trzy lata dla Swifta brzmią dla mnie jak 50 lat dla ludzkości. Byłem całkiem pewien, że sytuacja nie jest tak zła, jak myśli ta osoba, ponieważ wiem, że zespół Swift stale poprawia język, w tym czas kompilacji. Nie jestem taką osobą, która będzie się kłócić bez solidnych argumentów.

Benchmarking

W zeszły weekend miałem kilka godzin wolnych na sprawdzenie jego oświadczenia. Napisałem skrypt ruby, aby sprawdzić wydajność rozszerzeń w porównaniu z metodami. Podejście, które wybrałem, jest dość proste, prawdopodobnie nawet naiwne, ale i tak chciałbym zobaczyć pewne wyniki. Sprawdziłem następujące przypadki:

  • Metody klasy +
  • Rozszerzenia klasy +
  • Struktura + metody
  • Struct + Extensions

Skrypt Ruby tworzy n funkcji liczbowych dla każdego przypadku (w przykładzie n = 3):

Metody klasy +

klasa MyClass {
    niech n = 1000
    func method_1 () {
      dla pozycji w 0 .. 

Rozszerzenia klasy +

klasa MyClass {
    niech n = 1000
    func method_1 () {
      dla pozycji w 0 .. 

Chciałem też poznać odpowiedź na pytanie: ile rozszerzeń znajduje się w prawdziwych aplikacjach Swift? Sprawdziłem najpopularniejsze aplikacje open source napisane w Swift i kilka aplikacji, które opracowaliśmy w naszej firmie dla klientów dla wielu rozszerzeń.

Aby uruchomić testy, ustaw USE_EXTENSIONS na true lub false w Rakefile.

Uruchom testy:

test prowizji

Wyniki testów czyszczenia:

Grabie czyste

Wyniki

Jeśli chodzi o reprezentowanie zebranych danych w jasny i znaczący sposób, moje umiejętności analizy danych były bardzo przydatne. Stworzyłem skrypt main.py w języku Python, który generuje wykresy bokeh.

Interaktywne wykresy są dostępne tutaj: http://minikin.me/extensions

Środowisko testowe: macOS 10.13.4, Swift 4.1, 2016 MacBook Pro, 2,6 GHz Intel Core i7, 16 GB 2133 MHz LPDDR3

Wnioski

Średnio użycie metody metod wynosi od -6% do 70% tak szybko, jak równoważna implementacja z rozszerzeniami.

Ale czy to oznacza, że ​​nie powinniśmy używać rozszerzeń? Prawdopodobnie nie.
W rzeczywistych aplikacjach liczba rozszerzeń rzadko osiąga 1000, a jeśli tak, różnica wynosi około 20%.

Jasne, w prawdziwej aplikacji uzyskamy różne wyniki, ale mierzone w absolutnej różnicy czasu, oszczędności w większości przypadków raczej nie będą znaczące.

Jeśli chcesz eksperymentować, możesz sprawdzić repozytorium na GitHub.

Jeśli masz jakieś pytania, skontaktuj się ze mną: @minikin

Aktualizacja 1 (03.06.2018):

Yarik Arsenkin poprosił mnie o dodanie testu porównawczego dla przypadku Klasa + Funkcje prywatne w rozszerzeniu vs Klasa + Metody prywatne. Sprawdź zaktualizowane wykresy i wyniki.