Dlaczego nie pojawia się szybszy, „lepszy” język niż C? [Zamknięte]

147

Skoro obecnie dostępne są wszystkie nowe „nowoczesne” języki, to w jaki sposób C jest nadal uważany za najszybszy i „najbliższy maszynie”? Naprawdę nie wierzę, że kiedykolwiek istniałby tylko jeden właściwy sposób na robienie rzeczy, a C istnieje już od bardzo dawna (od lat 60.!). Czy naprawdę nie wymyśliliśmy nic lepszego niż coś napisanego prawie 50 lat temu?

Wiem, że współczesne języki są na wyższym poziomie i zajmują się niektórymi zadaniami, takimi jak wyrzucanie elementów bezużytecznych i przydzielanie pamięci, a także wykorzystanie bibliotek i tym podobnych. Pytam tylko, dlaczego nigdy nie istniała prawdziwa druga opcja dla C.

Czy to możliwe, że C jest tak doskonały, że żaden inny sposób obsługi komputera nie byłby możliwy (poza przyjęciem programisty)?

EDYCJA Słuchaj, nie próbuję obalić C ani żadnego innego ulubionego języka. Zastanawiam się, dlaczego C stał się standardem i dlaczego inne alternatywy nigdy się nie pojawiły, a C został po prostu „zaakceptowany”.

Jason
źródło
44
C ++ jest równie szybki i znacznie wydajniejszy w pisaniu. <3
GManNickG
6
um, nie zapominasz o c ++?
23
Twierdziłbym, że montaż jest najszybszy i „najbliższy” do maszyny.
27
dlaczego wszystkie ruchy do zamknięcia? jestem naprawdę ciekawy ... nie próbuję rozpętać wojen płomiennych ani nic takiego
Jason
15
ponownie zamknięte? po ponownym otwarciu przez samego Jeffa Atwooda? dlaczego miałbyś chcieć to zamknąć?
Jason

Odpowiedzi:

164

C jest bardzo prostym językiem i właśnie z tego powodu, wraz z długowiecznością, jest szybki i zoptymalizowany. Jest również wyjątkowo szeroko obsługiwany w przypadku środowisk osadzonych, mikroprocesorów itp.

Trudno jest pokonać naprawdę prosty i szybki język. Jedyną rzeczą, którą można ulepszyć w takim języku, jest użyteczność: skróć czas potrzebny do stworzenia podobnego, ogólnego kodu i ułatw modelowanie za pomocą abstrakcji.

W tym momencie pojawia się C ++. C ++ może być tak samo szybki jak C. Chodzi o to, że C ++ jest znacznie bardziej złożonym językiem, co oznacza, że ​​zdecydowanie zwiększa wydajność; tak długo, jak ludzie wiedzą, jak go używać. C ++ i C niejuż prawie tym samym językiem.

Teraz D był kolejnym krokiem. Ta sama zdolność do szybkiego kodu, opcjonalnego wyrzucania elementów bezużytecznych itp., Ale nigdy się nie przyłapała. Mam nadzieję, że to się zmieni, ponieważ porzuca to, co nęka C ++: wsteczna kompatybilność z C.

Tak więc odpowiedź na pytanie „lepsza” jest trudna do oceny. Pod względem prostoty i szybkości C jest prawdopodobnie zbliżone do tego, co mogliśmy zrobić. Jeśli chodzi o produktywność w porównaniu z prostotą, C ++ jest prawdopodobnie najlepszym, co możemy zrobić, choć ta opinia różni się znacznie bardziej. Wreszcie, jeśli chodzi o dopracowany i uporządkowany język, z szybkością i prostotą języka C, D wygrywa w tym kontekście.

GManNickG
źródło
31
Przez „prosty” rozumiesz „prosty z kompilatora POV, a nie programisty POV”. C jest prosty, ponieważ zasadniczo składa się z instrukcji i wyrażeń. Nie jest prosty sposób, w jaki Python jest prosty.
Marius,
15
Ale do wyjaśnienia, proste dla kompilatora ma oznaczać prosty odebrać. Być może nie jest to łatwe do wprowadzenia w życie skomplikowanych pomysłów.
GManNickG,
16
O ile jest to warte, OCaml produkuje wysoce zoptymalizowany kod natywny tak szybko jak C i C ++, a sam kod jest tak zwięzły jak Python. Przy odrobinie dopracowania, myślę, że OCaml mógłby dopasować lub pobić C jako język wyboru, gdy trzeba pisać kod dla maksymalnej prędkości i minimalnego zużycia pamięci. Objective-C również wykonuje całkiem niezłą robotę, chociaż nie zawsze jest tak szybki jak C, dostaje całą rzecz „C z obiektami” w sposób, w jaki C ++ nigdy nie mógł i nigdy nie będzie.
Juliet
2
Uzgodniona z @ Thorbjørn, wsteczna kompatybilność z C jest powodem, dla którego C ++ się przyłączył, a D nie. Jeśli jesteśmy gotowi zrezygnować z tego, nie ma powodu zadowalać się stopniową poprawą, jaką jest D. Moglibyśmy wybrać znacznie lepsze języki, które są całkowicie z rodziny C. Jak mówi @Juliet, OCaml może być opłacalnym konkurentem pod względem wydajności. Ale może i wiele innych języków, jeśli twórcy kompilatorów spędzili na nich tyle samo czasu, co na C lub C ++. W każdym razie dobra odpowiedź i +1 ode mnie.
lipiec
5
@Ferruccio: Tak, ale każdy język może zawierać linki do bibliotek C. Więc jeśli chcemy się na to zgodzić, zamiast rzeczywistej zgodności kodu źródłowego, jak oferuje C ++ (mniej więcej), równie dobrze moglibyśmy wybrać zupełnie inny język, powiedzmy Haskell lub Python. Powodem, dla którego C ++ się przyłapał, nie było to, że mógł linkować do bibliotek C. Było tak, że mógł skompilować kod C.
lipiec
64

Są szybsze niż języki C.

Są języki szybsze niż C. Na przykład Fortran, jak już wspomniano, radzi sobie bardzo dobrze, ponieważ ma znacznie bardziej ograniczone reguły języków aliasingu.

Istnieją również eksperymentalne asemblery, takie jak języki, które atakują C z przodu, gdzie jest używany jako język asembera wysokiego poziomu, na przykład do tworzenia kompilatorów. Słyszałeś kiedyś o C- lub Janusie? Ale ci dwaj zostali zabici przez projekt LLVM.

Założę się, że APL lub inne języki matematyczne wydmuchują C z wody w specjalnych domenach aplikacji, ponieważ mają wbudowane wsparcie dla jednostek przetwarzania wektorów. Jest to coś, co nie jest możliwe dla C (i ludzie: NIE! Specjalne zoptymalizowane biblioteki z łączeniem C nie mają nic wspólnego z C jako językiem).

Również producenci procesorów usunęli wszystkie elementy pomagające pisarzom kompilatorów w innych językach - pamiętasz oznakowane kody asemblerów arytmetycznych do szybkiego wdrożenia LISP na SPARC? Przeminęło z wiatrem.

A jeśli odejdziesz od mikroprocesorów do tworzenia aplikacji, wtedy są szybsze języki do tworzenia aplikacji. Moim osobistym przykładem jest tutaj SmartEiffel. Celuje w C, ale korzysta z globalnej optymalizacji systemu, co czyni go szybszym niż C w tworzeniu aplikacji w świecie rzeczywistym.

W tej dziedzinie nawet proste abstrakcje o złym lub niskim poziomie mogą zabić cały występ języka. Ponieważ C nie oferuje dużych abstrakcji, większość ludzi twierdzi, że jest to problem programistyczny, ale tak nie jest. Na przykład spójrz na brak leków generycznych. W C skończysz z powolnymi implementacjami, takimi jak funkcja biblioteki „qsort”, którą można napisać o wiele szybciej za pomocą generyków (gdzie eliminowane jest wywołanie funkcji dla porównań kluczowych).

Wystarczy porównać wywołanie qsort w megabajtowej tablicy ints z dobrą odręczną implementacją, która korzysta z dostępu do tablicy i wbudowanego operatora „<”.

Lothar
źródło
9
Bardzo dobry komentarz. Ważne jest, aby zdawać sobie sprawę, że niektóre aspekty specyfikacji języka C (takie jak reguły aliasingu wskaźników) uniemożliwiają wygenerowanie naprawdę optymalnego kodu maszynowego. Będąc asemblerem wysokiego poziomu, C nie jest „najszybszy”, ale jedynie „dość szybki”.
1
Dzięki zapomniałem wspomnieć o niemożności zwrócenia wielu wartości wyników. Kolejny aspekt niskiego poziomu, którego mi brakuje, gdy używam go jako asemblera wysokiego poziomu.
5
Nowoczesne C, poprawnie napisane, może zakodować te same założenia aliasingu, co każdy inny język, umożliwiając kompilatorowi dokonanie tych samych optymalizacji. Jest to ważna cecha języka, ponieważ pozwala również programiście nie przyjmować tych wymagań, gdy nie mają one zastosowania. Twoje pozostałe punkty są na miejscu, więc +1.
Stephen Canon
1
@Rascher: To prawda i tam widać wpływ C na projektantów procesorów, które zawsze określają ABI procesora. A wielokrotne zwracane wartości to coś, co po prostu nie przychodzi mi do głowy, nawet jeśli liczba rejestrów nie stanowiłaby problemu (SPARC, PowerPC, Itanium)
13
Aliasing wskaźnika w C został rozwiązany restrictw C99 (10 lat temu!).
35

Dobre pytanie. Myślę, że językom się udaje, znajdując niszę. Należy zauważyć, że istnieje wiele nowszych języków, które są lepsze niż C w swoich niszach.

  • C był kiedyś szeroko stosowany jako język aplikacji i w tej dziedzinie stopniowo tracił popularność w C ++, Javie, a ostatnio w wielu innych językach (zwłaszcza w językach dynamicznych).

  • C był kiedyś językiem do pisania kodu serwera. Sieć pchnęła w tę przestrzeń niesamowitą różnorodność języków - Perl, Java, Python, VBScript, VB.NET, Ruby, C # - i przypadki, w których C ma jakikolwiek sens dla kodu serwera, są teraz bardzo rzadkie.

  • C został wykorzystany do obliczeń naukowych, ale napotyka konkurencję ze strony języków specyficznych dla domeny, takich jak Matlab i Mathematica, a także bibliotek takich jak SciPy . Wiele osób, które piszą kod w tej niszy, nie jest programistami z zawodu, a C nie jest dla nich idealnym rozwiązaniem.

Ale niszą C jest kod systemowy. Jądra systemu operacyjnego. Kierowcy. Biblioteki wykonawcze. Jest tak ustalony w tej przestrzeni, że nawet C ++ przesuwa ją raczej powoli.

C wygrał w latach 70. dzięki systemowi UNIX, ponieważ konkurencyjne języki były albo zbyt restrykcyjne, albo zbyt wolne, a także dlatego, że kod C uznano za w miarę przenośny (kłamstwa, nawet wtedy). Ale jego największe zalety są dziś niezwiązane i wynikają głównie z dziesięcioleci dominacji w tej niszy. Istnieją dobre narzędzia do C: optymalizacja kompilatorów, debuggerów jądra, skuteczna analiza statyczna w celu znalezienia błędów w kodzie sterownika itp. Prawie każda główna platforma definiuje C ABI, a często jest to lingua franca dla bibliotek. Istnieje grupa programistów, którzy wiedzą, jak kodować C - i którzy wiedzą, jakie są problemy i pułapki C.

W dłuższej perspektywie ta nisza nie zniknie; a C ma pewne problemy. Ale dla nowicjuszy nadal byłoby bardzo trudno konkurować.

Jason Orendorff
źródło
9
C jest nadal szeroko stosowane w kodzie serwera. Istnieje nie tylko sieć, większość serwerów DNS, e-mail itp. Są napisane w C. Nawet w sieci Apache jest w C.
@bortzmeyer: Apache jest jednak dość stary. Nie twierdzę, że to nie jest użyteczne lub zostało zastąpione, zostało stworzone, gdy było C i nie było wielu dobrych alternatyw.
Macke,
1
Zastanawiam się, dlaczego uważasz C za „niedoskonałe” do obliczeń naukowych. Python jest wprawdzie przyjemniejszy w pracy, ale odkryłem, że C jest solidną alternatywą, gdy potrzebny jest szybszy kod, a wiele z możliwych alternatyw (C ++) nie przynosi dużo więcej do tabeli, w przeciwieństwie do innych aspektów programowania .
Fomite
1
Poza tym ilość rzeczy w SciPy / NumPy itp., Które są napisane w C, sprawia, że ​​warto wiedzieć.
Fomite
1
@EpiGrad Może C to dla Ciebie solidna alternatywa. Ale C ma bardzo stromą krzywą uczenia się, szczególnie dla osób, które nie mają doświadczenia w kodowaniu. W szczególności czasami się zawiesza, a jeśli nie jesteś programistą, nie masz wielkiej nadziei na rozwiązanie tego problemu. Mathematica ułatwia pisanie ogromnej liczby rzeczy i kończy się na tym, że kod jest mniejszy o setki razy. I nie upaść.
Jason Orendorff
25

Parafrazując bardzo dobry komentarz: Nie ma wielu różnych sposobów na uczynienie języka szybkim i „zbliżonym do maszyny” - C zrobił to dobrze i nie ma na to miejsca.

Oryginalna odpowiedź:

Szybkie wykonanie lub szybkie pisanie?

Języki nie są szybkie lub powolne do wykonania, są konkretne implementacje. Język można uznać za szybszy niż inne tylko wtedy, gdy w jakiś sposób ułatwia szybkie wdrożenie . Niezmiennie oznacza to „blisko maszyny”. Ale wraz z przyspieszaniem wykładniczym maszyn stało się to z czasem coraz mniej interesujące. Zamiast tego łatwość i szybkość rozwoju oraz przenośność stały się znacznie ważniejsze, dlatego „lepszy” stał się oznaczeniem „z dala od maszyny” . Prawie wszystkie wysiłki w zakresie projektowania języka podążały w tym kierunku przez ostatnie 5 dekad.

Oto jesteś: bliżej maszyny i szybszych języków niż C; to te, które pojawiły się przed C : Asembler, Fortran. Prawdopodobnie niektóre zapomniane.

Michael Borgwardt
źródło
@ Michael - ale wciąż istnieje rynek super-lean, super-szybkiego programowania, szczególnie z atakiem wszystkich tych urządzeń mobilnych ... dlaczego C jest nadal najlepszą opcją dla niektórych z tych urządzeń, tj. dlaczego nie ma innego język na tym poziomie, taki jak .NET-vs-Python-esque?
Jason
5
Seplenienie. Drzemka, ale nie zapomniana! :)
2
@Jason: Pytanie brzmi, ile przenośnych asemblerów potrzebujesz? C jest dobrze znany i bardzo trudno jest napisać język z szybszą implementacją, więc po co? W garniturze nie ma wymagań, rynku, motywacji.
4
@ Michael, przepraszam, że skomentowałeś swoją odpowiedź. Powodem, dla którego jest więcej w python / ruby ​​/ java itp., Jest to, że kiedy przestaniesz próbować najbardziej efektywnego języka, otrzymasz o wiele więcej opcji, które funkcje nadać priorytet, a każde podejście może dać nowy język. Istnieje znacznie mniej sposobów na napisanie najszybszego możliwego języka.
1
-1 dla „i nie ma już co poprawiać” - jest dużo miejsca do poprawy w C / C ++ bez wpływu na wydajność.
BlueRaja - Danny Pflughoeft
21

Fortran jest szybszy niż C do zadań numerycznych ze względu na sposób, w jaki obsługuje odniesienia do pamięci (wskaźniki C trudniej jest zoptymalizować). Ciężkie biblioteki numeryczne u podstawy takich rzeczy jak Matlab i Numpy są nadal zapisane w Fortranie.

Z drugiej strony C ++ może być tak samo szybki jak C, ale ma wiele bardziej zaawansowanych funkcji programowania. Jest to znacznie nowszy język z połowy lat 80-tych.

zaharpopov
źródło
1
C ++ jest wciąż aktualizowany.
GManNickG,
5
@GMan: podobnie jest C.
3
Popraw mnie, jeśli się mylę, ale czy restrictwskaźnik C99 nie miałby takiej samej semantyki aliasingowej jak Fortran? A co jeszcze ma na to wpływ?
9
Myślę, że idea, że ​​Fortran jest szybszy niż C, jest nieco mitem, w zależności od tego, co jest kodowane i kto to robi. Powodem, dla którego ciężkie biblioteki numeryczne są w Fortranie, nie jest to, że Fortran jest szybszy, ale dlatego, że procedury zostały pierwotnie zakodowane w Fortran i niewiele osób ma odwagę lub musi je ponownie napisać. Niewielka liczba guru matematyki, którzy piszą i weryfikują te algorytmy, jest szczęśliwa w Fortranie i nie widzi potrzeby zmiany, zwłaszcza że wyobraża sobie, że Fortran jest szybszy.
Mike Dunlavey,
16

Co do cholery, wrzucę moje 0,02 $.

W wielu przypadkach istnieje rzeczywista lub postrzegana różnica między językami „systemowymi” a językami wyższego poziomu. Zignoruję większość języków „wyższego poziomu”, ponieważ nikt (przynajmniej niewielu) będzie argumentował, że w przypadku wielu zadań języki takie jak Python, Ruby itp. Są łatwiejsze w obsłudze.

C został zaprojektowany jako język systemowy, co oznacza, że ​​został zaprojektowany jako język, w którym napisano system operacyjny Unix. Jako taki został zaprojektowany jako prosty, wydajny i szybki. Prosty język zyskuje na sile dzięki temu, że programiści niesystemowi często uważają za niebezpieczne: wskaźniki, ręczne zarządzanie pamięcią itp. Jak już wspomniano, C jest dość prosty. K&R to jak dotąd najmniejsza książka na mojej półce programistycznej (nie licząc O'Reilly Pocket References) i jest tylko nieznacznie „większa” niż moja Ruby Pocket Reference. C jest dość silny. Jeśli potrzebujesz porozmawiać ze sprzętem, sprawdź ręcznie i zmień pamięć, itd. C ma taką możliwość.

Jednak z perspektywy programisty C nie jest takie proste. Szybkość i moc są w cenie ręcznego zarządzania pamięcią i niewielkiej obsługi OOP wbudowanej w język. C ++ (nie mój ulubiony język) jest znacznie prostszy z perspektywy programisty, ale o wiele mniej prosty z perspektywy kompilatora. Objective-C (prawdopodobnie mój ulubiony język) ma ten sam kompromis, z lekkim pochyleniem w kierunku utrzymania prostoty języka (zbieranie śmieci jest nowością w Objective-C, na przykład). Ponieważ jednak świat komputerowy, jak wielu z nas wie, został napisany w języku C, trudno jest rozpowszechnić nowe, bardziej skomplikowane, ale „łatwiejsze” języki.

W niektórych przypadkach, zwłaszcza gdy obecny „standard” jest tak „wystarczająco dobry” jak C, po prostu nie ma zachęty do czegoś „lepszego” (C ++, Objective-C, D itd.), Aby uzyskać przyczepność, gdy jest jest nawet wystarczającą zachętą do stworzenia czegoś „lepszego”.

alesplin
źródło