Czy prototypowanie w języku wyższego poziomu jest powszechne? [Zamknięte]


18

Obecnie bawię się pomysłem rozpoczęcia projektu, który znacznie przekracza moje obecne umiejętności programowania w języku, w którym mam bardzo małe doświadczenie w świecie rzeczywistym (C). Czy warto byłoby prototypować w języku wyższego poziomu, z którym jestem bardziej zaznajomiony (np. Perl / Python / Ruby / C #) tylko po to, abym mógł rozpocząć cały projekt?

Ostatecznie produkt końcowy jest wrażliwy na wydajność (jest to silnik bazy danych), stąd wybór C, ale obawiam się, że brak znajomości C spowoduje, że stracę las dla drzew.

Podczas szukania podobnych pytań zauważyłem wspomnienie, że programiści używali prototypów w Prologu, a następnie wypakowali je w asemblerze.


4
Słyszałem o ludziach, którzy piszą asembler, najpierw kodując to, czego chcą w C, a następnie demontują go i ręcznie dostrajają powstały zestaw.
user16764

9
Nie zapominaj, że wydajność najczęściej sprowadza się do prawidłowego wyboru i implementacji algorytmu, pisania równoległego kodu dla kłopotliwych równoległych problemów i dobrej reprezentacji danych. Nie przejmuj się C, dopóki nie uzyskasz właściwego projektu.
Peter Smith,

1
@ user16764: Właściwie to zrobił. Tyle że językiem był Fortran. Ale ręcznie poprawiliśmy dane wyjściowe kompilatora dokładnie tak, jak opisano.
S.Lott

C niekoniecznie jest szybszy. Zwłaszcza jeśli wydajność jest związana z IO. Nawet jeśli chodzi o wydajność związaną z procesorem, jeśli nie jesteś ekspertem C, zoptymalizowana maszyna wirtualna prawdopodobnie przewyższy wszystko, co sam napiszesz.
jiggy

Często używam tej techniki prototypowania: problem jest wyrażany w jego najbardziej naturalnym języku, który ostatecznie jest implementowany jako DSL. Następnie, kiedy prototyp jest gotowy, zamiast przekodowywać część DSL na język niższego poziomu, poprawiam implementację tego kompilatora DSL, aż wydajność jest do zaakceptowania.
SK-logic

Odpowiedzi:


27

Użycie C nie powoduje automatycznie przyspieszenia aplikacji. Jeśli masz możliwość wyboru innego języka programowania dla swojej platformy, bardzo go polecam.

Jak stwierdził Bill Harlan :

Łatwiej jest zoptymalizować poprawny kod niż poprawić zoptymalizowany kod . Przedwczesna optymalizacja faktycznie utrudnia optymalizację na dłuższą metę. Niepotrzebna optymalizacja zniekształca projekty, niszczy modułowość i ukrywanie informacji oraz znacznie utrudnia modyfikację kodu. Znalezienie ukrytych błędów trwa dłużej. Często odkrywamy, profilując lub zmieniając maszyny lub kompilatory, że źle oceniliśmy wysiłek obliczeniowy naszego kodu. Zgadnij co? Teraz optymalizacja jest znacznie trudniejsza niż musiała być.

Jeśli naprawdę potrafisz przewidzieć problemy z wydajnością, rozważ użycie C ++. cprogramming.com bardzo ładnie to ujmuje :

Można zastanawiać się jednak, czy warto rezygnując z ponownego wykorzystania C ++, aby uzyskać niewielki wzrost wydajności z C, zwłaszcza gdy C ++ mogą, tam gdzie to konieczne, być napisane w stylu programowania C .


Aby lepiej odpowiedzieć na twoje aktualne pytanie: napisałbym kod w języku wyższego poziomu, nie tylko prototypował go, a optymalizowałbym tylko w językach niższego poziomu, gdy napotkasz problemy z wydajnością.


25
+1: Również Perl, Python i Ruby mogą wywoływać funkcje C, więc w razie potrzeby możesz napisać wrażliwe na wydajność części w C.
Larry Coleman

Prototypowałem kod widzenia maszynowego w Javie; Okazało się, że był wystarczająco szybki. Przekodowanie do C byłoby dość łatwe (piszesz to po prostu jak C; używając prymitywnego antifatternu)
Tim Williscroft

Napisałem kod w czasie rzeczywistym w Javie. W tym konkretnym projekcie dostęp do plików został wykonany w C ++, a kod czasu rzeczywistego był w Javie - szalone! Jednak kod czasu rzeczywistego był niesamowicie szybki. Nie było to bardzo skomplikowane, ale poradziło sobie z niesamowitą ilością danych w mgnieniu oka. Powiedziałbym więc, że zdecydowanie możesz używać języków wysokiego poziomu do aplikacji wrażliwych na wydajność.
konfigurator

@Tim Williscroft: Wydaje mi się, że wyświetlam tę samą stronę tylko wtedy, gdy szukam w Google hasła „prymitywny antipattern naprawczy”. Co to jest?
SingleNegationElimination

@TokenMacGuy: prymitywna obsesja ma więcej trafień (ten sam antypattern)
Tim Williscroft

7

Nie byłoby to przydatne, ponieważ a) części tych języków, które tłumaczą bezpośrednio na C, nie byłyby prostsze, oraz b) części, które nie tłumaczą bezpośrednio na C, byłyby trudniejsze do przepisania w C niż jeśli w ogóle napisałeś je w C.


+1 - Zwłaszcza, że ​​trudno byłoby zmienić kod OO na C, jeśli nie znasz języka, lub sprawiłoby, że używanie języka wysokiego poziomu byłoby bardziej niewygodne, jeśli piszesz w sposób proceduralny.
Jetti

Tak, dokładnie. Martwię się, że wciąż myślę o wyższych koncepcjach, które nie są łatwo tłumaczone na język C, na przykład gdybym używał zbyt dużej ilości magii lub cukru.
Mark Canlas

4

To nie jest pytanie z kategoryczną odpowiedzią tak lub nie. Pozwól mi ważyć się z anegdotą.

Przykład 1

Miałem za zadanie przeniesienie gry napisanej w Javie do Flasha, AS3. Na powierzchni może to przebiegać stosunkowo płynnie. W końcu możesz uznać takie zadanie za bardziej przejrzyste niż praca przeciętnego klienta, ponieważ masz już całkowicie wbudowaną specyfikację funkcjonalną w postaci gry źródłowej. Java i AS 3 są językami wysokiego poziomu, a AS3 ma wiele wspólnych cech z Javą, takich jak struktury pakietów, dziedziczenie pojedyncze / wiele interfejsów, silne wpisywanie (opt-in) oraz pojęcia zmiennej publicznej / chronionej / prywatnej i deklaracje funkcji. W tym czasie byłem bardzo zielony w Javie i zupełnie nowy w oryginalnej bazie kodu źródłowego. Więc po prostu zanurkowałem, żeby zobaczyć, co mogę znaleźć, mając nadzieję, że będzie to szybkie i łatwe.

Jak się okazało, autor kodu próbował stworzyć abstrakcyjny silnik, który można by przenieść z Javy do jakiegoś nieokreślonego innego środowiska. To dało mi nadzieję, że przeniesienie będzie proste. Niestety, zamiast tego odkryłem, że patrzę na perspektywę ponownego wynalezienia samego Flasha na Flash, bez korzyści z Wątków. Jak się okazało, dosłowny port byłby po prostu złym pomysłem ... koszmarem wydajności. Poza tym gra zaimplementowała własny niestandardowy zewnętrzny język skryptowy, co oznaczałoby utworzenie parsera i leksykonu dla tego języka, gdybym miał nadzieję korzystać ze wszystkich oryginalnych źródłowych plików danych.

Ostatecznie, biorąc pod uwagę ograniczenia czasowe i budżetowe, oryginalny kod źródłowy nie bardzo pomógł. Najbardziej pomocne było to, że wiedziałem, jak dokładnie naśladować kontrolę nad logiką gry ... ale czy naprawdę potrzebowałem do tego oryginalnego źródła? Prawdopodobnie nie.

Ale ten przykład może nie być tak istotny, ponieważ jest swego rodzaju odwrotnością twojej sytuacji. Miałem nadzieję, że użyję bazy kodu, której nie napisałem, w języku, który nie znałem w tym czasie, aby przyspieszyć rozwój w środowisku, które dobrze znałem. Oto inny przykład

Przykład 2

Zwracając uwagę na to, co robił programista Java, próbując stworzyć przenośną bazę kodów, postanowiłem zrobić coś podobnego dla siebie w pracy z Flashem ... pisząc kod, który nie polegał tak bardzo na rozszerzeniu klas flash.display. * i używając kompozycji do tworzenia widoków. Nie polegam tak mocno na flash.event. * I zamiast tego piszę własny, lekki system przekazywania wiadomości, niepowiązany szczególnie z językiem ani platformą. Niedawno skończyłem grę używając wspomnianego frameworka i chciałem przekonać się, czy łatwo byłoby go przenieść na C # (język, który znam tak bardzo, jak jest podobny do Java i AS3) jako projekt Unity 3D. Jak się okazuje, było to o wiele bardziej udane! Ponieważ myślę płynniej w AS3 niż w C #, posiadanie już napisanych algorytmów oszczędza mnóstwo czasu. Wszystko, co musiałem zrobić, to po prostu zmienić składnię, co nie jest

Tak więc, z własnego doświadczenia, nie mogę powiedzieć, że odpowiedź zawsze brzmi „tak” lub „nie”. Powinieneś wziąć pod uwagę, w jakim stopniu jesteś zależny od określonych idiomów językowych w wybranym języku wysokiego poziomu i czy ponowne ich utworzenie będzie łatwe czy trudne w C.


Twoja druga historia pokazuje, jak się czuję. Starałbym się zachować ogólną implementację prototypu i swobodę magii / sztuczek, tak aby większość, jeśli nie wszystkie pomysły, można było przetłumaczyć na C. Łatwiej powiedzieć niż zrobić, ale myślę, że na wystarczająco wysokim poziomie nadal jest on w stanie utrzymać. Oczywiście diabeł tkwi w szczegółach.
Mark Canlas

@Mark Canlas „diabeł tkwi w szczegółach”. Absolutnie. Myślę, że możliwe, że twoja pierwsza próba pójdzie nie tak, jeśli nigdy wcześniej nie przenosiłeś kodu między językami lub środowiskami tylko dlatego, że trudno jest przewidzieć wszystkie potencjalne problemy, dopóki ich nie napotkasz.
scriptocalypse

2

Myślę, że warto zacząć od pseudokodu. Pisanie prototypu w innym języku wydaje się potencjalną stratą czasu, ponieważ Twój język wyższego poziomu prawdopodobnie nie przełoży się na „C” prawie tak dobrze, jak pseudokod.

Ponadto, używając pseudokodu, lepiej zrozumiesz, jak naprawdę działa twój system.

W tym samym okresie, w którym pracujesz nad pseudokodem, powinieneś uczyć się C. Następnie, zanim skończysz planować, być może będziesz gotowy do rzeczywistej implementacji.

Ponieważ proponowanym powodem napisania go w innym języku była pomoc w rozpoczęciu projektowania, możesz zamiast tego skorzystać z diagramów UML lub czegoś podobnego, aby zacząć.


2

Możesz prototypować algorytm - wyeliminować błędy projektowe podstawowej logiki, używając zdecydowanie „bardzo wysokiego poziomu” języka (powiedzmy Matlab, może Ruby). Użyj go, aby udowodnić, że Twój algorytm działa i działa poprawnie, a następnie zaimplementuj go od zera w języku „niskiego poziomu”.

Nie zyskasz dużo, jeśli wybierzesz C ++, a nawet Javę lub C # jako „wysoki poziom” i C jako „niski poziom”, ponieważ wzrost czytelności nie będzie znaczący, a „tłumaczenie” będzie nadal bardzo bolesne i całkiem błędne skłonny. Chodzi o to, że silnik twojego projektu w implementacji wysokiego poziomu nie powinien zajmować więcej niż jednego lub dwóch ekranów, być łatwy do uchwycenia, łatwy do odczytania, a wszystkie zastrzeżenia muszą być bolesne oczywiste - w zasadzie działający blok, który można uruchomić diagram.


2

Mechanizm bazy danych polega głównie na optymalnym obsługiwaniu niskiego poziomu operacji we / wy i efektywnej obsłudze złożonych struktur, takich jak b-drzewo i listy połączone.

Jest to z pewnością problem C / C ++, chociaż istnieją pewne całkiem dobre implementacje Java.

Opracowywanie poprawnych algorytmów, które działają dobrze, jest znacznie łatwiejsze w języku wyższego poziomu. Zwykle chodzi o wypróbowanie kilku odmian i porównanie wyników. Następnie możesz przetłumaczyć algorytm „zwycięski” na C.

Rozwiązaniem kompromisowym może być napisanie początkowej implementacji w jednym z języków JVM wyższego poziomu (przychodzą na myśl Jython, Groovy), a następnie przeniesienie klasy po klasie na Javę, gdy implementacja się ustabilizuje.


2

Nie wydaje mi się, żeby było to powszechne, ale jest gotowe. Jeden z najostrzejszych architektów, z którymi kiedykolwiek współpracowałem, wykonał jego modelowanie w Pythonie, a następnie zaimplementował ten kod w C ++.

Ogólnie rzecz biorąc, aby było to warte zachodu, myślę, że naprawdę musisz wykonywać złożone i wysoce zoptymalizowane algorytmy, które nie są łatwo wyrażone w prosty sposób w języku docelowym. W większości sytuacji „w świecie rzeczywistym / biznesowym” stosunkowo łatwo jest wyrazić intencje na wysokim poziomie w tym samym języku, na który celujemy, a implementacja w tym języku spełnia nasze wymagania dotyczące wydajności, więc nie ma potrzeby / chęci modelowania w wyższej poziom języka.

Biorąc pod uwagę twoją sytuację, w której masz lepszą znajomość języka wyższego poziomu, mogłem zobaczyć, jak ta metodologia sprawdza się w krótkim okresie. Nie tylko dostarczy Ci mapę drogową, aby utrzymać porządek, ale jeśli masz pytania, będziesz mógł zadawać je z większą precyzją.


1

Obecnie pracuję nad projektem napisanym w C „ze względu na wydajność” (to była pierwotna motywacja), ale w rzeczywistości po profilowaniu ujawnia, że ​​spędza większość czasu na oczekiwaniu na inne systemy (DB, inne aplikacje napisane w Java, „zdarzenia” na gnieździe).

Jeśli użyjesz złego algorytmu, uzyskasz również słabą wydajność w C (np. Jeśli przeprowadzasz liniowe wyszukiwanie klucza, „ponieważ C nie ma tabel mieszających i nie chcemy używać innych bibliotek”, idziesz wolniej niż gdybyś zrób to z językiem, który ma tabele skrótów lub podobne, takie jak C ++, Java, C #, Python ... i tak dalej).

Jeśli jesteś zmuszony zrobić to w C z jakiegokolwiek powodu, to prototypowanie w innym języku, który znasz, nie jest dla mnie tak złym pomysłem tylko wtedy , gdy prototypujesz wiedząc, które „problemy” będziesz miał podczas rzeczywistej implementacji C, to trudne, jeśli nie masz pewności co do C. (Wkrótce odkryjesz np., że biblioteki std C / C nie mają kontenerów, tylko „zwykłą” tablicę; potrzebujesz bibliotek innych niż std). Co więcej, C nie jest OO, więc jeśli prototypujesz w sposób OO, będzie trudniej.

Podsumowując, najlepszą rzeczą do zrobienia jest wykonanie rzeczywistej implementacji w języku „prototypowania”, a następnie, naprawdę potrzebne, napisanie funkcji intensywnie wykorzystujących procesor w C, ale jeśli tylko C jest akceptowalny, naucz się go lepiej, zanim wykonasz prototyp w innym języki i oczywiście przed napisaniem implementacji.


1

Istnieje wiele aplikacji o krytycznym znaczeniu dla wydajności napisanych w języku wyższego poziomu.

W przeszłości programowałem w Asemblerze i C. I chociaż jest to całkiem fajne uczucie tak bliskie metalowi, ich użycie jest obecnie bardzo ograniczone.

Jest tak wiele rzeczy, które utrudniają działanie, że wątpię, czy kiedykolwiek dojdziesz do tego, gdzie sam język jest czynnikiem ograniczającym. To biorąc pod uwagę, że jest to C vs C #.

Załóżmy, że otrzymujesz wzrost wydajności o 10–15% według języka. To nic w porównaniu ze wzrostem rzędów wielkości przy wdrażaniu poprawnego algorytmu.

Podczas programowania w języku C # będziesz miał znacznie więcej czasu na skoncentrowanie się na architekturze i implementacji algorytmów / struktur danych, co prowadzi do lepszych optymalizacji wyższego poziomu.

W prawdziwym świecie zawsze masz ograniczony czas, więc spędzaj czas na właściwej części projektu.


0

Jestem ciekawy, jaki jest twój plan stworzenia go w C? Czy zamierzasz prototypować, a następnie nauczyć się języka C, a następnie ponownie go zakodować w języku C? Wydaje mi się to trochę przysłowiowym „wzrokiem większym niż żołądek”, który, jak sądzę, przyciąga wielu programistów podczas nauki nowych technologii (wiem, że mam). Chodzi mi o to, że próbujesz zaprojektować coś, co jest wyraźnie wrażliwe na wydajność, nawet nie znając tajników języka, w którym Twoim zdaniem musi on zostać napisany, w zasadzie chcesz już zacząć projektować aplikację C przed sobą poznaj C, kiedy lepiej spędzić czas, najpierw ucząc się C, a następnie możesz uzyskać lepszy wgląd w sposób pisania wybranej aplikacji. Być może pomyliłem pytanie, a ty zamierzasz przekazać to innemu programistowi, aby zbudował program w C,


Czasami „nie rób tego”. jest poprawną odpowiedzią na „Jak zrobić X?”
Larry Coleman,

0

Prototypowanie jest czasem wykonywane, aby zrozumieć problem, który próbujesz rozwiązać. A czasem, aby poznać podstawowe technologie, jeśli jeszcze się nie znasz.

W omawianym przypadku rozważasz stworzenie prototypu w języku skryptowym, powiedzmy python, i utworzenie rzeczywistego kodu w C.

Ocena niektórych możliwości:

1 . Prototypujesz w pythonie i piszesz oprogramowanie w C.

Prototypowanie w języku skryptowym może pomóc w szybkim sprawdzeniu wyników pod kątem danych wejściowych . Jest to przydatne, jeśli musisz przede wszystkim przetestować logikę w celu rozwiązania problemu. Przydatne również, jeśli chcesz szybko przygotować wersję demonstracyjną dla innych osób.

Jakikolwiek kod napisany w Pythonie nie będzie używany w ostatecznym oprogramowaniu. Ale może pomóc, jeśli przekazujesz swój prototyp osobie, która potrafi czytać w Pythonie i pisać w C. Tutaj prototypowanie może pomóc w przekazaniu pomysłu .

Ta metoda jest odpowiednia do testowania logicznej wykonalności rozwiązania.

2) . Prototypujesz w C i piszesz oprogramowanie w C.

Prototypowanie w C, które jest dla Ciebie nowe, ma dwie zalety. Po pierwsze, pisząc prototyp, rozumiesz odpowiednie części języka , biblioteki, API, pułapek itp. Po drugie, podczas tworzenia ostatecznego oprogramowania możesz zacząć od samego prototypu , który oszczędza czas i ponownie wykorzystuje kod .

Ta metoda nadaje się do testowania logicznej i technologicznej wykonalności rozwiązania.

3) . Możesz rozważyć sposoby niekodowania prototypów w zależności od problemu.

Jeśli jest to jakaś logika i pomysły, które chcesz prototypować; pseudo kod , schematy blokowe i schematy blokowe na papierze też są dobre.

Jeśli jest to prototyp interfejsu użytkownika, rozważ narzędzie do tworzenia makiet interfejsu użytkownika lub ponownie papier.


0

Myślę, że powinieneś prototypować w języku, który znasz (Pytho / Ruby / C # what not), aby:

  1. W pełni wykorzystujesz udogodnienia / biblioteki oferowane przez język.
  2. Spędzasz czas na podejmowaniu decyzji dotyczących wyboru projektu zamiast ograniczeń językowych.

Później możesz użyć narzędzia do profilowania, aby znaleźć obszary szyjki butelki. Ponownie zaimplementuj w C / C ++. Powtórz powyższy krok kilka razy, kto wie, że Twój prototyp może być „wystarczająco szybki”!


0

Nie sądzę, abyś zyskał cokolwiek dzięki opisanemu przez ciebie podejściu, a kilka osób szczegółowo opisało, dlaczego tak się dzieje.

W jednym projekcie, w który byłem zaangażowany, zastosowano takie podejście: tworzenie bibliotek matematycznych dla architektur Cell / BE i Power7. Funkcje zostały modelowane w Haskell (przy użyciu CoCoNUT), a funkcje wyjściowe były w zoptymalizowanym zestawie dla konkretnej architektury docelowej.

W tym przypadku celem była wysoka wydajność z dostrajanymi instrukcjami montażu i umiejętnością kierowania na wiele architektur.

Jedzenie jednak, mam nadzieję, że nie umrzesz z głodu :)


0

W przypadku wysokowydajnego silnika bazy danych prawdopodobnie potrzebujesz:

  • wielowątkowość,
  • jawne zarządzanie pamięcią,
  • powiadomienia asynchroniczne,
  • semafory lub operacje podstawowe synchronizacji,
  • łatwy dostęp do funkcji systemu plików niskiego poziomu.

Wybrane algorytmy mają kluczowe znaczenie dla wydajności.

Ogólna rada to zacząć od języka wysokiego poziomu, a następnie migrować tylko te bity, które wymagają optymalizacji do języka niższego poziomu.

jednak wybrany przez ciebie język wysokiego poziomu musi obsługiwać algorytmy, które musisz napisać: wydajne algorytmy mogą ostatecznie zostać zdominowane przez kontrolę wątków, efektywne wykorzystanie pamięci i wykorzystanie najlepszych operacji na systemach plików niskiego poziomu dostępny. Jeśli więc celem końcowym jest wydajność, nie można prototypować w językach, które nie obsługują prymitywów, których należy użyć.

Jeśli musisz przetestować swój prototyp (lub inne osoby muszą opracować oprogramowanie pod kątem interfejsów), musisz także pracować w języku, który obsługuje zamierzone interfejsy API. Następnie możesz pozwolić innym osobom na przetestowanie kodu i przeprowadzenie własnych testów regresji podczas optymalizacji.

Te rozważania prawdopodobnie wykluczają wiele języków do prototypowania na wysokim poziomie w tym przypadku - i prawdopodobnie wszystkie te, o których wspomniałeś (z wyjątkiem ewentualnie C #). Ale możesz oczywiście pseudo-kod w dowolnym języku (w tym angielskim) i, jeśli to konieczne, możesz prototypować części projektu (na przykład funkcje sortowania) w preferowanym języku.

Bliski związek między C ++ i C (oraz znikome różnice w wydajności) oznaczają, że istnieje bardzo niewiele powodów, aby nie preferować C ++ w porównaniu do C w produkcie końcowym.

(Odpowiadam na założenie, że potrzebujesz wysokowydajnego silnika bazy danych do określonego celu: jeśli twoje zamiary są skromniejsze, to prawdopodobnie wybierzesz istniejący silnik z półki).


-2

Myślę, że sława C jest zasłużona, ponieważ wspaniały produkt Unix został napisany w C. Jednak w porównaniu do ludzi, którzy znają C najlepiej, jestem sceptycznie nastawiony do tego, dlaczego należy go używać. Mówi się, że Ken Thompson (po napisaniu pierwszej wersji Uniksa w języku asemblera) zaczął pisać Unix w Fortranie, ale poddał się po tygodniu lub miesiącu i zaczął używać C, który był rozwijany przez jego kolegę Kena Ritchiego z o tym samym czasie.

Zaskoczyło mnie ostatnio, że Fortran jest szybszy niż C i C ++.

Richard Mullins


1
Jak to odpowiada na zadane pytanie?
komara
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.