Czy kod naukowy jest na tyle inną dziedziną, aby zignorować wspólne standardy kodowania?


21

Ostatnio próbuję ogarnąć następujący fakt.

Z jednej strony istnieje szereg wytycznych i standardów kodowania dla tego, co jest uważane za „zdrowe”, „czyste”, „dobrze napisane” i tak dalej. Zobacz też „Czysty kod”, który wydaje się być tutaj szeroko omawiany. Przykładowa reguła: metody o długości 7 linii i 1 lub 2 poziomy wcięcia. Oczekuje się, że kod, który nie następuje, umrze z powodu złej konserwacji.

Z drugiej strony, mogę pracować z OpenCV, OpenCascade, VTK itp. To jest kod naukowy. Mają 2-stronicowe metody (sen ja), OpenCascade ma metodę lub klasę podzieloną na 10 plików (tutaj nie ma żartów), VTK też jest czasem bałagan. Jednak projekty te rozwijają się, są utrzymywane i szeroko stosowane!

Gdzie jest haczyk? Czy wolno nam pisać naukowy, wymagający matematyki kod, który po prostu działa i możemy go utrzymać? Czy jesteś oddzielnym zestawem standardów dla takich projektów, jeśli takie istnieją?

Może to być naiwne pytanie, ale jestem w czymś, co wydaje się pustką programistyczną, próbując stworzyć zestaw zasad, jak robić i nie robić rzeczy, w taki sposób nauczono mnie pracy w szkole średniej. Odkąd ukończyłem szkołę, nie miałem prawie żadnych wytycznych w zakresie rzeczy, które musiałem robić, głównie programowania - nikt nie zawracał sobie głowy nauczaniem tego.


25
Nie, nie jest, ale większość naukowców nie ma wykształcenia inżynieryjnego, aby wiedzieć lepiej.
Gort the Robot

4
W każdym projekcie, który istnieje już od jakiegoś czasu, znajdziesz mnóstwo źle napisanego kodu, ale wydaje się, że działa wystarczająco dobrze, aby nikt nie zawracał sobie głowy, aby wrócić i go wyczyścić. Czasami dzieje się tak dlatego, że standardy i wzorce ewoluują z czasem, czasem dlatego, że standardy nie były egzekwowane jednolicie, czasem dzieje się tak, ponieważ dodawanie nowych funkcji jest znacznie przyjemniejsze niż cofanie się i refaktoryzacja fragmentu kodu, który działa, ale jest słabo udokumentowane.
Justin Cave

2
@JustinCaveL Lub: „Jeśli się nie zepsuło, nie naprawiaj tego”. Szczególnie dotyczy kodu tylko do zapisu . Zobacz także plaza.ufl.edu/johnaris/PDFs/ProblemSolvingFlowChart.pdf
Robert Harvey

Na pewno znajdziesz moje wcześniejsze pytanie istotne: programmers.stackexchange.com/q/266388/620
rwong

8
Kolegom Główni odpowiadający: To pytanie odnosi się do bazy kodu z bibliotek open-source dla obliczeniowych zadań w jednej lub kilku dziedzin naukowych . To pytanie nie dotyczy kodu jednorazowego. Zatrzymaj się na chwilę, aby upewnić się, że rozumiesz każdy wyróżniony aspekt przed napisaniem odpowiedzi. Dzięki.
rwong

Odpowiedzi:


28

Czy kod naukowy jest na tyle inną dziedziną, aby zignorować wspólne standardy kodowania?

Nie, nie jest.

Kod badawczy jest często „wyrzucany” i zapisywany przez osoby, które nie są programistami ze względu na pochodzenie, bez względu na swoje kwalifikacje akademickie. Część kodu, który napisałem, sprawiłaby, że płaczę . Ale zadziałało!

Jedną rzeczą do rozważenia jest to, że strażnicy projektów kierują tym, co zostaje uwzględnione. Jeśli duży projekt rozpoczął się jako projekt kodu akademickiego / badawczego, kończy się działaniem, a teraz jest bałaganem, ktoś musi podjąć inicjatywę, aby go przeredagować.

Zmodyfikowanie istniejącego kodu, który nie powoduje problemów, zajmuje dużo pracy. Zwłaszcza jeśli jest w ogóle specyficzny dla domeny lub nie ma testów. Zobaczysz, że OpenCV ma przewodnik po stylach, który jest bardzo obszerny, nawet jeśli nie idealny. Stosujesz to z mocą wsteczną do całego istniejącego kodu? To znaczy ... nie dla osób o słabym sercu.

Jest to jeszcze trudniejsze, jeśli cały ten kod działa. Ponieważ to nie jest zepsute. Po co to naprawiać?

Jednak projekty te rozwijają się, są utrzymywane i szeroko stosowane!

W pewnym sensie jest to odpowiedź. Działający kod jest nadal użyteczny i dlatego jest bardziej prawdopodobne, że zostanie utrzymany.

Może to być bałagan, szczególnie na początku. Niektóre z tych projektów prawdopodobnie rozpoczęły się jako projekt jednorazowy, który „nie wymagałby ponownego wykorzystania i mógłby zostać wyrzucony”.

Weź również pod uwagę, że jeśli wdrażasz złożony algorytm, sensowniejsze może być posiadanie większych metod, ponieważ ty (i inni znający stronę naukową) lepiej rozumiesz algorytm. Moja praca dyplomowa dotyczyła optymalizacji. Posiadanie głównej logiki algorytmu jako jednej metody było znacznie łatwiejsze do zrozumienia, niż próbowałoby to rozdzielić. Z pewnością naruszyło zasadę „7 wierszy na metodę”, ale oznaczało również, że inny badacz mógł spojrzeć na mój kod i szybciej zrozumieć moje modyfikacje algorytmu.

Gdyby to wdrożenie zostało wyabstrahowane i dobrze zaprojektowane, ta przejrzystość zostałaby utracona dla programistów .

Do innych użytkowników: To pytanie odnosi się do bazy kodu bibliotek typu open source do intensywnych obliczeniowo zadań w jednej lub wielu domenach naukowych. To pytanie nie dotyczy kodu jednorazowego. Zatrzymaj się na chwilę, aby upewnić się, że rozumiesz każdy wyróżniony aspekt przed napisaniem odpowiedzi.

Myślę, że ludzie często mają taki pomysł, że wszystkie projekty open source zaczynają się od „hej, mam świetny pomysł na bibliotekę, która będzie bardzo popularna i używana przez tysiące / miliony innych”, a potem każdy projekt tak się dzieje.

Rzeczywistość polega na tym, że wiele projektów jest uruchamianych i ginie. Śmiesznie niewielki odsetek projektów „dociera” do poziomu OpenCV lub VTK itp.

OpenCV powstał jako projekt badawczy firmy Intel. Wikipedia opisuje to jako część „serii projektów”. Jego pierwsza wersja niebędąca wersją beta miała miejsce w 2006 roku, czyli siedem lat po jej uruchomieniu. Podejrzewam, że początkowo celem były znaczące wersje beta, a nie idealny kod.

Ponadto „własność” OpenCV uległa znacznej zmianie. To powoduje zmianę standardów, chyba że wszystkie odpowiedzialne strony przyjmą dokładnie te same normy i zachowają je przez czas trwania projektu.

Powinienem również zauważyć, że OpenCV istniał przez kilka lat, zanim opublikowano Manifest Agile, z którego czerpie inspirację Clean Code (a VTK prawie 10). VTK został uruchomiony 17 lat przed opublikowaniem Clean Code (OpenCV był „tylko” 9 lat wcześniej).


2
Korzystałem z OpenCV w 2004 roku i było to okropne. Willow Garage (nowi właściciele ) wykonali świetną robotę, przekształcając prawie wszystko w C ++. W rzeczywistości jest to jedna z niewielu bibliotek naukowych, które składają się z dobrego kodu.
nimcap

15

Naukowcy nie są programistami. Ich zadaniem nie jest pisanie kodu per se. Ich zadaniem jest rozwiązywanie problemów, a programowanie jest tylko jednym z narzędzi, z których mogą korzystać.

Większość kodu napisanego przez - jak by to nazwali - profesjonalnych programistów to bałagan. Większość tego kodu nie używa wzorców projektowych ani ich nie używa. Większość komentarzy to kandydaci do TheDailyWTF . Ponieważ w naszej branży widzimy takie wyniki od osób, których praca polega na pisaniu kodu, czego można oczekiwać od osób, których zadaniem nie jest pisanie programów?

Czy wszystkie praktyki, których rzeczywisty profesjonalny programista uczy się podczas swojej kariery, przyniosłyby korzyści naukowcom? Absolutnie. Czy każdy naukowiec mógłby spędzić pięć do dziesięciu lat swojego życia na tworzeniu oprogramowania? Prawdopodobnie nie. Dlatego jakość kodu jest taka, jaka jest.

Kolejnym czynnikiem jest kultura. Jeśli twoje pary nie piszą czystego kodu, dlaczego miałbyś? Ponieważ nikogo to nie obchodzi, tak naprawdę nie masz ochoty na dodatkowy wysiłek.

Wreszcie, większość kodu naukowego ma stosunkowo krótką żywotność. Piszecie kod dla konkretnego badania, a kiedy badanie zostanie zakończone, nie będziecie go ponownie wykorzystywać. Kiedy masz już ten nawyk, trudno jest odróżnić biblioteki wielokrotnego użytku, takie jak te, które przytaczasz, i kod wyrzucający.


„Ich zadaniem nie jest pisanie kodu per se. Ich zadaniem jest rozwiązywanie problemów” - zauważ, że technicznie zadaniem programisty nie jest także pisanie kodu. Jego / jej zadaniem, podobnie jak naukowca, jest rozwiązywanie problemów. Wykluczam fabryki oprogramowania i małpy kodowe, które są opłacane za utrzymanie krzeseł w cieple, ale z definicji nie dbają też o czysty kod, więc nie mają znaczenia dla tego pytania :)
Andres F.

8

Ignorować? Nie. Ponownie rozważyć i dostosować? Pewnie. Wiele kodu naukowego wymaga intensywnej matematyki i ma kluczowe znaczenie dla wydajności. Rzeczy takie jak narzut wywołania funkcji mogą w rzeczywistości stać się problemem, więc możesz skończyć z głębiej zagnieżdżonymi strukturami niż w typowej aplikacji komercyjnej. To nie znaczy, że powinieneś najpierw zanurzyć się w tysiąc mikrooptymalizacji. Nadal powinieneś skupić się na wyborze odpowiedniego algorytmu i dokonywać tylko optymalizacji, których efekt można zmierzyć.

Niektóre różnice są oczywiste i trywialne. Wytyczne kodowania zazwyczaj wymagają wybrania znaczących nazw zmiennych, a nazwy jednoliterowe będą natychmiast podejrzane. Aplikacja naukowa nadal będzie chciała znaczących nazw zmiennych, ale czasami najbardziej znaczącą nazwą będzie pojedyncza litera, odnosząca się do zmiennej w dobrze znanym równaniu.


4
+1 za komentarz do nazewnictwa zmiennej. Kiedy byłem w szkole, pracowałem jako niezależny programista dla różnych działów, a na wydziałach statystyki i matematyki byłem „bardzo zachęcany” do używania nazw zmiennych, takich jak Aji, T0ponieważ w taki sposób nazwy zmiennych były nazywane w funkcjach, które tłumaczyłem na kod. Używanie czegoś takiego correlationIndexlub startTimenarzekałoby.
TMN

4

Wszystkie istniejące odpowiedzi kompleksowo obejmowały to pytanie. Chciałbym jednak wskazać, jaki jest prawdziwy antypód między takimi jak OpenCV itp., A na przykład kod opracowany zgodnie z dobrymi praktykami biznesowymi (Code Complete, Clean Code, SOLID itp.)

Zasadniczo kod źródłowy ma być KISS ma wiele korzyści biznesowych - bądź prosty, głupi”. Istnieje również powiązany YAGNI - „Nie potrzebujesz go”.

Niestety, w przypadku intensywnego obliczeniowo oprogramowania w domenach naukowych kod źródłowy rzadko jest prosty lub ubogi .


Tradycyjnie OpenCV cierpiał na brak uogólnień (wiele duplikacji kodu w celu obsługi różnych opcji), podczas gdy VTK cierpiał na nadmierne uogólnienia (szablony).

Na początku niektóre części OpenCV zostały pierwotnie opracowane w C. Później OpenCV przyjął API C ++, które znamy dzisiaj. Niektóre algorytmy zostały przepisane, aby wykorzystać interfejsy C ++ (abstrakcyjne klasy podstawowe) i szablony C ++. Inne algorytmy były po prostu opakowaniami oryginalnego kodu C. Pozostałości tego kodu można znaleźć rozrzucone w module „imgproc”.

OpenCV zawiera wiele programów SIMD (wektoryzacja). Do tej pory programowanie SIMD w C ++ nadal wymaga użycia intrinsics (intel.com) , (arm.com) .

Cechy wewnętrzne SIMD czytają jak język asemblerowy, z tym wyjątkiem, że kompilator zajmuje się przypisywaniem zmiennych do rejestru, a kompilatorowi może swobodnie zmieniać kolejność instrukcji dla zwiększenia wydajności. Algorytmy napisane w celu użycia wewnętrznych funkcji SIMD miały wysokie koszty utrzymania. Z tego powodu wspomniałem wcześniej zadane pytanie - Koszt utrzymania bazy kodu programowania SIMD .

Osoba, która nie wykonuje programowania SIMD, może łatwo przekonać się, że SIMD można elegancko obudować i że programowanie SIMD niskiego poziomu nie powinno być już konieczne. W rzeczywistości jest to dość dalekie od prawdy. Rzuciłbym każdemu wyzwanie, aby spróbował zaimplementować użyteczny algorytm w SIMD (nie fraktale) i dostrzegł trudność użycia w tych proponowanych enkapsulacjach.


Poniżej znajduje się długa lista pomysłów, gdy próbuję przeanalizować, dlaczego oprogramowanie obliczeniowe nie może być KISS lub YAGNI. Jednak wszystkie te pomysły są nadmiernymi uogólnieniami i nie wydają się potwierdzać powyższej obserwacji.

Głównymi czynnikami przyczyniającymi się są:

  • Wydajność oprogramowania
  • Konieczność obsługi wielu opcji algorytmu i kompromisów
  • Konieczność obsługi wielu różnych platform sprzętowych i kompilatorów
    • Jest to związane z problemem wydajności oprogramowania - wydajność musi być dobra dla wielu platform sprzętowych i kompilatorów.
  • Brak ciągłej modernizacji bazy kodu z powodu braku zasobów, brak wiedzy osób, które mogłyby poprawić jakość kodu bez narażania innych czynników itp.
    • Projekty open source cierpią z powodu tragedii społeczności .
    • Projekty o otwartym kodzie źródłowym, które otrzymują dotacje, musiały spełniać określone cele - jakość kodu zazwyczaj nie jest ich częścią.
    • W szczególności brakuje nawet kompetentnych osób, które mogłyby wprowadzić lub zasugerować stopniowe ulepszenia jakości kodu . Jest to problem „brakujących gałek ocznych” - wiele osób korzysta z kodu, ale niewiele z nich czytało.
  • Historyczny brak bramek jakości kodu, takich jak przegląd kodu, testy jednostkowe, analiza statyczna itp.
    • W przypadku projektu na dużą skalę te bramki jakości kodu nie są jedynie ręcznymi krokami - każde wymagałoby infrastruktury (system internetowy, system testów jednostkowych, system automatyzacji kompilacji itp.)

Niektóre z powyższych czynników są antypodami rozwoju oprogramowania biznesowego:

  • Zazwyczaj oprogramowanie biznesowe nie musi radzić sobie z tymi samymi wysokimi przepływnościami danych, jakie występują w oprogramowaniu obliczeniowym.
  • Oprogramowanie biznesowe można powiązać z jednym systemem operacyjnym i architekturą komputera.
  • Oprogramowanie biznesowe może być oszczędne w podejmowaniu decyzji, jakie funkcje należy uwzględnić. W rzeczywistości tworzenie oprogramowania biznesowego zachęca menedżerów do odmawiania nowych funkcji, o ile nie ma uzasadnienia biznesowego.
    • Użytkownicy wewnętrznego oprogramowania biznesowego mogą zostać przeszkoleni w zakresie wykonywania różnych czynności, unikając konieczności wprowadzania zmian w kodzie.
    • Jeśli oprogramowanie komercyjne traci jednego klienta z powodu jednej brakującej funkcji, ale zyskało dwóch nowych klientów z powodu ulepszonej prostoty i łatwości użytkowania (patrz „Paradoks wyboru” ), ogólnie jest to zysk netto - jest to dobry rzecz, której brakuje tej jednej funkcji.
  • Oprogramowanie biznesowe jest wspierane przez ciągły strumień przychodów, dzięki czemu jest w stanie wydać jego część na ciągłą modernizację bazy kodu.

1
Przynosisz do stołu wiele punktów, które wydają się dość nieistotne dla pytania.
Martin Maat

@MartinMaat Jeśli masz coś pozytywnego do dodania do tego pytania, napisz własną odpowiedź.
rwong

3

Czy kod naukowy jest na tyle inną dziedziną, aby zignorować wspólne standardy kodowania?

Zależy to od tego, co nazywacie „wspólnymi standardami kodowania”. Nie nazwałbym ekstremów Agile „wspólnymi”. W szczególności uznanie funkcji, która ma osiem linii za zbyt długą lub która ma więcej niż dwa poziomy wcięcia za zbyt skomplikowane, jest absurdalnym standardem w dziedzinie programowania numerycznego / naukowego.

Bardzo prosta funkcja macierzy razy macierzy ma więcej niż siedem linii i ma trzy poziomy wcięcia. Funkcja ta stanie się znacznie bardziej złożona niż ta, którą należy się obawiać o wydajność. Jest to tak powszechna operacja, że ​​ważna jest wydajność. Rozbicie go na kawałki jest dokładnie tym, czego nie chcesz robić. Rozkład macierzy będzie jeszcze bardziej złożony.


2
„Agile” nie ma nic wspólnego ze standardami kodowania.
Gort the Robot

@StevenBurnap - Pewnie, że tak. Spójrz na „Wyczyść kod”. Zawiera wiele standardów kodowania.
David Hammen,

1
Czysty kod mający wiele standardów kodowania jest złym argumentem. Manifest Agile może nie mieć nic wspólnego ze standardami kodowania, ale Agile promuje elastyczność i reagowanie na zmiany i przestrzeganie standardów kodowania lub najlepszych praktyk to wspiera. Tak więc - w bardzo pośredni i ostrożny sposób zwinny może nie mieć nic wspólnego ze standardami kodowania, ale standard kodowania ma wiele wspólnego ze zwinnym.
Marjan Venema

1

Postanowiłem opublikować to jako nową odpowiedź, ponieważ jest to zupełnie inna perspektywa.

Rzućmy okiem na przykładowy kod, który uważam za „czysty kod” pod względem widzenia komputera i zrozumienia obrazu:

https://github.com/opencv/opencv/blob/05b15943d6a42c99e5f921b7dbaa8323f3c042c6/modules/photo/src/seamless_cloning_impl.cpp

Dla osób zaznajomionych z MATLAB i obliczeniami naukowymi kod w C ++ jest prawie tak zwięzły, jak najczystszy możliwy kod MATLAB.


Teraz musimy zapytać, dlaczego cała baza kodu biblioteki (w tym przykładzie OpenCV) nie jest zapisana w tym samym standardzie co przykładowy kod?


Musimy rozwarstwiać bazę kodu dużej biblioteki naukowej na poziomy abstrakcji .

Na niskim poziomie dosłownie ponownie wdrażasz dodawanie i odejmowanie. Lub dosłownie mapowanie każdej operacji na najszybsze implementacje na każdej platformie.

https://github.com/opencv/opencv/blob/master/modules/core/src/hal_replacement.hpp

Na poziomie średnim znajduje się „najbrudniejszy” kod, w którym może spędzić około 80–90% czasu wykonywania procesora. (Podobnie, może 80% - 90% nakładów programistycznych zostało wydanych na poziomie średnim, jeśli liczymy oddzielnie nakłady programistyczne od badań naukowych).

Na wysokim poziomie mamy najczystszy kod napisany przez naukowców.


Konieczna jest silna doskonałość w organizacji kodu źródłowego, aby upewnić się, że poziomy te się nie mieszają. To wykracza poza standardy kodowania , więcej ma związek z zarządzaniem open source .

Na przykład czasami podejmowana jest decyzja o podzieleniu jednego projektu typu open source na dwa. Nie możesz sprawić, by te rzeczy się wydarzyły za pomocą zatwierdzeń kodu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.