Czy narzut metody celu-c powoduje, że podejście do projektowania „wielu małych metod” jest niewskazane?

15

Generalnie wolę używać małych metod, zalecanych między innymi przez Boba Martina w Clean Code . Przeczytałem również wystarczająco dużo o wewnętrznych elementach Objective-C, aby mieć przynajmniej pojęcie o tym, jak działa wysyłanie wiadomości ( seria bbums jest szczególnie pouczająca na ten temat).

Niezależnie od przedwczesnej optymalizacji, chciałbym wiedzieć, czy cała ta praca, którą wykonuje Objective-c z objc_msgSend, jest w praktyce wystarczająco znacząca, aby podejście „wiele małych metod” było niewskazane dla projektów Objective-C.

Szczególnie mile widziane są ustalenia empiryczne (może kiedyś sami przygotuję test). Świetne byłoby również doświadczenie każdego, kto napisał duże projekty typu C.

Wyjaśnienie

Ogólny ton pytania jest zamierzony. Nie pytam o dostrajanie wydajności określonych aplikacji (dlatego pytam tutaj, a nie na SO), ale raczej o to, czy cechy językowe Objective-C zniechęcają do określonego podejścia projektowego. Zauważyłem, że znaczna część kodu, który widziałem od Apple, i innych stron (na github itp.) Zmierza w kierunku dużych metod (i klas) i zastanawiam się, czy jest to błąd, który wkradł się z powodu języka samo. Oczywiście mogłem czytać niewłaściwy kod lub mogą to być czynniki kulturowe, a nie techniczne, które doprowadziły do ​​tendencji, jeśli taka istnieje.

(O ile warto, obecnie piszę Objective-C i używam małych metod)

Dalsze zapytanie

Zgadzam się z obydwoma udzielonymi odpowiedziami. Kolejną rzeczą, którą chciałbym, jest to, aby ktoś wskazał mi (miejmy nadzieję, że znaczną) otwartą (lub w inny sposób widoczną) bazę kodu Objective-C, która wykorzystuje ładne krótkie metody (i małe klasy). Nie widziałem jeszcze nic w Objective-C, aby porównać (na przykład) źródło fitnesse .

Cris
źródło
1
Mike Ash ma parę fajnych postów z liczbami dla Leoparda i iOS . Nie przetrawiłem ich w pełni, ale wydaje się, że w przypadku IMP w pamięci podręcznej narzut jest nieznaczny, a nawet w przypadku wysyłek wymagających wyszukiwania jest dość mały. Jeśli to szybkie wrażenie jest właściwe, wydaje się, że małe metody mogą stać lub spaść na tych samych podstawach projektowania w ObjC, jak w każdym innym języku.
Cris,
1
Jeśli chcesz uniknąć tego narzutu, użyj funkcji C.
prawej
Technicznie możliwe, ale wiele straconych funkcji. Metody zastępowałbym jedynie funkcjami dla ukierunkowanych, wrażliwych na wydajność części kodu. Pytam tutaj o to, czy koszty ogólne są wystarczająco problematyczne, aby ponownie rozważyć preferowany styl kodowania / projektowania.
Cris,
Aby uzyskać dobre odpowiedzi, zobacz Koszt wysyłki wiadomości w Objective-C na SO.
Caleb
Dlaczego po prostu nie profilujesz swojego kodu w Xcode? Rozumiem, że pytasz w sposób abstrakcyjny, a nie o konkretny kod, ale ponieważ najwyraźniej masz jakiś kod z wieloma małymi metodami, dlaczego nie uruchomić go i przekonać się sam?
Caleb

Odpowiedzi:

4

Naprawdę nie wiem, czy koszty ogólne są znikome, czy nie. Wolałbym jednak zaprojektować system tak, aby był najpierw zrozumiały i łatwy w utrzymaniu , co zwykle oznacza małe, skoncentrowane metody i klasy. Pomoże to nawet w późniejszym strojeniu kodu (tylko dlatego, że kod jest łatwiejszy w utrzymaniu). Ważne jest również profilowanie kodu, aby znaleźć prawdziwe wąskie gardła, które mogą nawet nie być związane z narzutem wywołania metody. Jeśli wykonujesz jakieś operacje poza procesem (np. Wywołania bazy danych, sieci, systemu plików), i tak mają one tendencję do dominowania w czasie wykonywania programu.

Ale jak zwykle przebieg może się różnić ...

Jordão
źródło
Oczywiście zgadzam się z tym wszystkim (patrz pytanie „wujek Bob” w pytaniu). Ale jeśli język nie nadaje się ogólnie do najlepszego podejścia projektowego, programiści mogą dokonać innych wyborów. Nie widziałem zbyt wiele kodu Objective-C, który tak naprawdę podąża za małymi metodami (i klasami), i zastanawiam się dlaczego. Dodam notatkę do pytania.
Cris
@Cris: „Nie widziałem zbyt wiele kodu Objective-C, który naprawdę stosuje małe metody” -> Po prostu ciekawy: z jakiego fragmentu kodu wyciągnąłeś taki wniosek? Wierzę w to, ale wierzę również, że nie dzieje się tak ze względu na świadomość mikrooptymalizacji, ale z większej liczby programistów, którzy nie koncentrują się na założeniach dobrego projektu i łatwości konserwacji. Innymi słowy, ich Java, C #, Ruby lub jakikolwiek inny kod muszą być zgodne z tymi samymi praktykami ...
Jordão
Tak, to całkiem możliwe. Nie miałem na myśli żadnej konkretnej bazy kodu; dokładnie to, na co patrzyłem przez około rok. Pracowałem z Objective-C. Największym zestawem kodu, na który patrzyłem, były pliki open source grupy Omni i IIRC, które miały wiele dużych metod. Przykładowy kod Apple również często tak robi. Ale oczywiście (a) przykładowy kod jest po prostu taki, i (b) moja próbka może być ważona w kierunku kodu interfejsu użytkownika, w szczególności kontrolerów widoku, i mogą one być kodowane inaczej niż głębsze warstwy.
Cris
2

Zdecydowana większość kodu nie będzie miała krytycznego wpływu na wydajność w żadnej aplikacji, więc nawet jeśli narzut metody byłby znaczny w porównaniu z innymi językami, optymalnym podejściem nadal byłoby posiadanie wielu małych metod w większości miejsc i umieszczanie tylko tych profilujących okazało się mieć krytyczne znaczenie dla wydajności.

Oczywiście jest wiele osób, które nie wiedzą, jak właściwie zoptymalizować, a niektóre z nich mogą wiedzieć o narzutach metod i angażować się w akty globalnej przedwczesnej optymalizacji, ale nie sądzę, że grupa jest wystarczająco duża, aby mieć znaczący wpływ w ekosystemie Objective-C.

Duże metody i klasy są znacznie bardziej prawdopodobne, że będą dziełem dużej grupy ludzi, którzy nie wiedzą ani nie dbają o profilery, narzut metody lub odpowiedni projekt i którzy będą mieli tendencję do tworzenia Big Balls of Mud w dowolnym języku. I tak, niektóre z tych osób pracują nad znanymi bazami kodów w największych firmach programistycznych.

Michael Borgwardt
źródło