Studiowałem trochę algorytmów i patrzyłem na strony takie jak SPOJ.pl TopCoder itp. Widziałem, że programiści preferują C lub C ++ zwykle w większości konkursów programowania algorytmicznego.
Teraz mam ostatnio problemy. Znam trochę C i Pythona, a kiedy próbuję napisać kod, wydaje mi się, że wolę Pythona od C dla większości algorytmów. Za każdym razem, gdy siadam, aby napisać kod w CI, poddaję się po około 15 minutach, ponieważ uważam, że jest to zbyt kłopotliwe i zwykle przechodzę do Pythona. Przekazywanie macierzy Wskaźniki i tak dalej wydają się być bezużytecznym marnowaniem czasu, który mógłbym wykorzystać do myślenia o samym algorytmie.
Teraz wiem i słyszałem od wielu ludzi, że C jest bardzo ważnym językiem i jest chlebem powszednim wielu programistów.
Chciałem wiedzieć, czy to moje podejście ma jakieś wady / konsekwencje / wady itp.
To nie jest debata Python kontra C; To pytanie o to, w jaki sposób ta szczególna praktyka preferowania Pythona nad C ze względu na łatwość użycia wpłynie na mnie lub dowolnego innego programistę / naukowca na dłuższą metę.
Bardzo chciałbym usłyszeć od osób, które używały tych języków w branży / i / lub do opracowania dużego oprogramowania / bibliotek itp.
źródło
Odpowiedzi:
Z mojego doświadczenia wynika, że gdy ludzie mają nadmierne problemy z kodowaniem algorytmów w C, często dzieje się tak, ponieważ ściśle łączą zarządzanie strukturą danych z algorytmem zamiast tworzyć odpowiednie abstrakcje. Na przykład, ręcznie manipuluj połączonymi wskaźnikami list wszędzie zamiast tworzenia
push()
ipop()
funkcji. Są zbyt przyzwyczajeni do dostarczania im tych abstrakcji.Podczas gdy ten problem jest znacznie bardziej widoczny w przypadku abstrakcji niższego poziomu, brak rozpoznania ścisłego powiązania i tworzenia odpowiednich abstrakcji jest problemem na każdym poziomie. Ćwiczenie tych umiejętności w C, dopóki nie będziesz w stanie stworzyć algorytmu, który wygląda na czysty i czytelny, zostanie przeniesiony na dowolny używany język.
Innym problemem, który czasami widzę wśród programistów Pythona, jest trudność dostosowania się do wydajności na dużą skalę. To prawda, że wydajność nie jest zwykle głównym problemem, ale najbardziej pythoniczny sposób implementacji algorytmu dla stosunkowo małej struktury danych może zatrzymać system, gdy pracujesz z gigabajtami lub więcej danych. Stanie się dobrym programistą C pomaga ci być bardziej świadomym tego rodzaju problemów w dowolnym języku.
Czy potrafisz nauczyć się tych umiejętności w innych językach? Jasne, ale C pomaga, czyniąc to bardziej oczywistym, gdy popełnisz błąd.
Biorąc to pod uwagę, używam Pythona do programowania algorytmicznego, kiedy mam wybór, nawet jeśli tak samo dobrze czuję się w C. Python ma funkcje językowe, które sprawiają, że jest bardzo przyjemny dla tego rodzaju programowania, a różnice w wydajności są zwykle znikome. Nie mogę powiedzieć, dlaczego inni programiści, którzy znają oboje, wybiorą C. Wyobrażam sobie, że wielu z nich robi to po to, aby wyróżnić się z tłumu.
źródło
Naukowcy, których głównym zainteresowaniem nie jest programowanie, wolą języki wyższego poziomu, takie jak Python, ponieważ mogą łatwiej kodować rozwiązanie w takich językach niż, powiedzmy, C. Python jest do tego szczególnie odpowiedni, ponieważ jest bardziej „prototypowy”, ponieważ jest „baterie w zestawie” i integruje się z bibliotekami numerycznymi, takimi jak NumPy i SciPy.
Jeśli badacz potrzebuje lepszej wydajności, zwykle przekazuje algorytm utworzony w Pythonie Inżynierowi oprogramowania, który znajdzie sposoby na jego optymalizację (w tym przekodowanie w C).
źródło
Pamiętaj, SPOJ.pl, konkurs ACM i wszystkie podobne konkursy koncentrują się na szybkim tworzeniu działającego kodu, który zostanie wyrzucony zaraz po zawodach. TopCoder robi to, ale w mniejszym stopniu (kod jest przynajmniej właściwie zorganizowany na poziomie projektowania OO).
Jednak w prawdziwym świecie programowania prawie każdy skrót, który bierzesz w konkursach programowania algorytmicznego, jest anty-wzorcem. Tylko jeśli weźmiesz to pod uwagę, możesz dokonać dowolnego porównania. Weźmy twój przykład: przekazywanie wielowymiarowej tablicy między różnymi funkcjami. W środowisku konkursowym najlepszym podejściem byłoby po prostu zadeklarowanie tablicy jako globalnej, aby zaoszczędzić czas na ustalenie właściwych szczegółów wywołania (np. Czy powinienem przekazać rozmiar, czy można to ustalić?). W prawdziwym programowaniu zrobiłbym dokładnie odwrotnie.
Więc na twoje pytanie, czy są jakieś złożone konsekwencje wyboru Pythona zamiast C dla algorytmów, powiedziałbym, że nie. Jeśli interesuje Cię tylko algorytm, zrobisz to samo w Pythonie i C. Implementacja go w języku funkcjonalnym może przynieść pewne różnice, ale algorytm jest taki sam.
Praktycznie jedyną rzeczą, którą zyskałeś, wdrażając algorytm w C, jest większa kontrola nad wykonywaniem i gwarancja, że używasz tylko abstrakcji niższego poziomu. To nie jest mała rzecz, ponieważ w Pythonie większość złożoności jest ukryta. Ale jeśli problem nie jest trywialny w abstrakcjach wyższego poziomu, możliwe, że straciłeś tylko szybkość wykonywania, aw większości przypadków tak naprawdę nie próbujesz zrobić programu tak szybko, jak to możliwe, po prostu uczysz się .
Jak już zasugerowano, zawsze można zamienić implementację Pythona na implementację C, jeśli Python okaże się zbyt wolny. Ale stanie się to prawdopodobnie 2-3 razy w wielkim projekcie, więc rozpoczęcie pracy w C może być stratą czasu, chyba że jest to Twój wybrany język (i wskazałeś, że tak nie jest).
źródło
Jako długoletni członek TopCoder i okazjonalny użytkownik SPOJ mogę powiedzieć, że głównym powodem, dla którego wolę C / C ++ od innych języków w konkursach, jest jego surowa szybkość. Kiedy wykonanie programu jest zaplanowane na czas, istnieje ogromna presja, aby wybrać „najszybszy” język, jaki można uzyskać, ponieważ daje to więcej luzu w zakresie kodowania algorytmu. Mój postęp w TC przeszedł z Javy do C # na C ++.
Jednak taka sytuacja występuje częściej w konkursach niż w codziennym programowaniu: chociaż pisanie optymalnego kodu jest niezwykle ważne, względne znaczenie ukończenia kodu tak szybko, jak to możliwe, i uczynienie go tak łatwym do utrzymania, jak to zwykle możliwe, zwykle oszczędza kilka sto cykli procesora. Jeśli wygodniej kodujesz coś w Pythonie, bardzo często jest to preferowane rozwiązanie.
Ponadto Python oferuje funkcje wysokiego poziomu, które nie są dostępne w C ++. Budowanie ich jest często bardzo kosztowne, a czasem nawet niemożliwe (na przykład rozważ zbudowanie refleksji lub samodostosowującego się kodu w C ++). W takich przypadkach opieranie się na języku wyższego poziomu może również okazać się optymalnym rozwiązaniem.
źródło
Ten wzrost wydajności jest częstym powodem znacznego zmniejszenia liczby zadań w C i C ++.
Składają się na to dwie zasadnicze części. Pierwszym z nich jest programowanie algortihmic. Naprawdę nie ma znaczenia, jakiego języka użyjesz do wyrażenia algorytmu. Praca z samym algorytmem i dopasowanie właściwych do właściwych problemów to kluczowe elementy, więc nie ma prawdziwego problemu.
Druga część to wzrost wydajności. Używanie rzeczy, które zwiększają produktywność w miarę upływu czasu, to dobry nawyk i coś, co nie przyniesie ci nic poza korzyściami podczas kariery. Umiejętność wyrażania algorytmów w różnych językach jest bardzo pomocna, ale ta pomoc opiera się bardziej na tym, jakie idiomy używają języki niekoniecznie w tych językach.
Krótko mówiąc, nie martw się tym . To, czego używasz do wyrażania algorytmu, jest o wiele mniej ważne niż możliwość wyrażenia go w ogóle.
źródło
Zaletą używania języków wyższego poziomu, takich jak Python lub Ruby, jest to, że (1) ich składnia jest bardzo zbliżona do pseudokodu i (2) ich standardowe biblioteki zapewniają przydatne struktury danych od razu po wyjęciu z pudełka (koncepcja akumulatorów, o której wspomniał @Robert). Dlatego korzystanie z nich jest całkowicie w porządku. Używaj tego, co maksymalizuje produktywność, zamiast wybierać język tylko dlatego, że jest to główny nurt lub „fajne”.
źródło
Podczas programowania w językach „wyższego poziomu” niż C / C ++ nie będziesz się uczyć, jak działa komputer. Nie będziesz w stanie opracowywać takich rzeczy, jak systemy wbudowane, systemy operacyjne i sterowniki sprzętowe. Znajomość C pomaga również w nauce asemblera.
Ponadto znaczna większość wszystkich systemów o kluczowym znaczeniu jest wciąż rozwijana w C, więc możesz nie być w stanie pracować w kilku gałęziach oprogramowania (lotnictwo / motoryzacja / technika medyczna itp.), Nie wiedząc o tym.
źródło
Jeśli kiedykolwiek pojawia się pytanie dotyczące „wielkiej notacji O” i próbujesz to zmierzyć, może być trudniej zrobić w Pythonie, chyba że wiesz dużo więcej o tym, jak Python implementuje różne rzeczy, na przykład lista Python nie jest listą połączoną ; Sortowanie Pythonów to TimSort; Śmieci w języku Python są zbierane w określonych momentach ...
Zawsze łatwiej jest mi podłączyć program C do tego, co prawdopodobnie dzieje się na procesorze, ale nawet tutaj jest buforowanie procesora; podział czasu systemu operacyjnego; Optymalizacje kompilatora itp., Które mogą mieć wpływ na moją intuicję.
Szybsze jest pisanie i debugowanie kodu w Pythonie, więc kiedy mam wybór, najpierw piszę w Pythonie, koncentrując się na uzyskaniu czegoś, co zadziała. Dzięki temu działającemu programowi Python możesz często umieścić go w większym systemie i dowiedzieć się nie tylko, że działał, ale także czy był wystarczająco szybki lub pod jakim względem był wolny. Uzyskanie prawdziwych danych dotyczących wydajności pomaga wtedy zoptymalizować prędkość i pozwala przetestować wersję Pythona pod kątem późniejszych zapisów w Pythonie, C lub cokolwiek innego.
Wady używania samego Pythona polegają na tym, że czerpanie korzyści z algorytmów napisanych w oczekiwaniu na kompilację typu C do modelu procesora może być trudne. Wady korzystania z samego C są takie, jak powiedzieliście: świnia jest do pisania i debugowania, w wyniku czego zbyt często trzeba pisać własne biblioteki.
Myślę, że najlepiej byłoby używać ich obu (i innych języków), dopóki nie wyczujesz ich kompromisów. Sam byłem dobrym koderem C, ale teraz piszę bardzo mało oryginalnego kodu C, chociaż nadal muszę czytać (a czasem debugować) kod C w mojej pracy. Chociaż wolę Python, znam i nadal używam Perla i Awka (oraz sed, grep i sort oraz Tcl, C i ...).
źródło
Radziłbym ci spojrzeć na Scalę lub Clojure (ale użyj adnotacji typu). W niektórych przypadkach mogą być tak szybkie jak C, w innych są nadal znacznie szybsze niż Ruby / Python, a jednocześnie mają bardzo sumienie i wyraźną notację w przeciwieństwie do C ( IMHO ). Rozważ to vs kod C:
Również mają programowania funkcyjnego arsenał podobnego do Ruby / Python
map
,filter
,reduce
itp, które nie jest tak szybki jak rekurencja Iteracja lub zadzwoń ogon, jednak jest to nadal znacznie szybciej niż te w pełni dynamicznych języków skryptowych.źródło
Przez kilka lat pracowałem nad małą częścią dużej biblioteki C ++ i napisałem pracę licencjacką i magisterską w kontekście tej biblioteki. Nawiasem mówiąc, biblioteka jest biblioteką algorytmów bioinformatycznych i struktur danych.
Biblioteka jest wbudowana w C ++, ponieważ C ++ jest prawie idealny do specyficznych wymagań tej biblioteki i ogólnie do bibliotek algorytmów. Gdybym miał opracować inną bibliotekę algorytmów, a wybór języka byłby mój, prawie na pewno wybrałbym ponownie C ++.
Powodem jest nie tylko wydajność, ale także mocny system typów, który przede wszystkim zapewnia większe bezpieczeństwo typów, a po drugie umożliwia typom dokumentowanie używanego algorytmu. Z mojego doświadczenia może to znacznie poprawić czytelność i łatwość konserwacji.
To powiedziawszy, w przypadku prostych bazgrołów algorytmicznych i łamigłówek prawie zawsze używam Pythona (głównie dlatego, że brzmi prawie jak pseudo kod), chyba że chcę wypróbować, jak najlepiej sformułować problem w C ++. Jak dotąd nie rozwiązałem wielu problemów z SPOJ lub TopCoder, więc nie wiem, czy wydajność jest tak istotna, że użycie szybkiego języka jest kluczowe.
Ale zwykle liczy się poprawność algorytmu w celu jego zaliczenia. W takich przypadkach Python działa dobrze. Na przykład w przypadku problemów z Project Euler (które nie są określone w czasie, liczy się tylko prawidłowe rozwiązanie), Python jest doskonale dostosowany.
źródło