Bevorzugen Sie Python gegenüber C für die algorithmische Programmierung

16

Ich habe ein bisschen Algorithmen studiert und mir Websites wie SPOJ.pl TopCoder usw. angesehen. Ich habe gesehen, dass Programmierer C oder C ++ normalerweise für die meisten algorithmischen Programmierwettbewerbe bevorzugen.

Jetzt habe ich in letzter Zeit einige Probleme. Ich kenne sowohl ein bisschen C als auch Python und wenn ich versuche, einen Code zu schreiben, bevorzuge ich Python für die meisten Algorithmen. Jedes Mal, wenn ich mich hinsetze, um einen Code in C zu schreiben, gebe ich nach etwa 15 Minuten auf, weil ich es zu umständlich finde und dazu neige, zu Python überzugehen. Übergeben von Matrizen Zeiger und so weiter scheinen nutzlose Zeitverschwendung zu sein, die ich tatsächlich nutzen könnte, um über den Algorithmus selbst nachzudenken.

Jetzt weiß ich und habe von vielen Leuten gehört, dass C eine sehr wichtige Sprache ist und das Brot und die Butter vieler Programmierer da draußen ist.

Was ich wissen wollte war, ob dieser Ansatz von mir irgendwelche Nachteile / Konsequenzen / Nachteile etc. hat.

Dies ist keine Python-gegen-C-Debatte. Dies ist eine Frage darüber, wie sich diese spezielle Praxis, Python wegen der Benutzerfreundlichkeit C vorzuziehen, auf lange Sicht auf mich oder einen anderen Programmierer / Informatiker auswirken wird.


Ich würde gerne von Leuten hören, die diese Sprachen in der Industrie verwendet haben / und oder große Software / Bibliotheken usw. entwickeln.

volljährig
quelle
Dieses Thema ist ohne den Link zu dieser Diskussion nicht vollständig. lukeplant.me.uk/blog/posts/…
permeakra
11
@permeakra: Das ist nur ein Schimpfen, im Grunde genommen heißt es, dass das Lernen von Haskell und Python Sie in anderen Sprachen nicht besser macht, weil diese anderen Sprachen scheiße sind.
Robert Harvey
Es ist nicht nur ein Scherz, da es eine Beschreibung enthält, wie Python und Haskell den Geist ihres Benutzers beeinflussen, und viele Kommentare anderer Leute zu diesem Thema. Im Vergleich wird c jedoch nicht als Sprache auf niedriger Ebene verwendet, sondern etwas mehr auf hoher Ebene, aber die Idee ist dieselbe - man beginnt, Ideen aus einer anderen Sprache in eine Sprache zu übertragen, in der er gerade arbeitet, wodurch der Code nicht idiomatisch wird . Es mag eine gute Sache sein, aber ...
permeakra
1
Dies ist meine Sichtweise
Wayne Werner
Es wäre interessant gewesen, ein bisschen nicht-algorithmisches Programmieren zu sehen, was auch immer das ist.
SK-logic

Antworten:

14

Nach meiner Erfahrung ist es häufig so, dass Menschen mit übermäßigen Schwierigkeiten bei der Codierung von Algorithmen in C ihre Datenstrukturverwaltung eng mit ihrem Algorithmus koppeln, anstatt geeignete Abstraktionen zu erstellen. Manuelles Manipulieren von verknüpften Listenzeigern anstelle von make push()und pop()functions. Sie sind es zu gewohnt, sich diese Abstraktionen zur Verfügung stellen zu lassen.

Während dieses Problem bei Abstraktionen auf niedrigerer Ebene viel offensichtlicher ist, ist es auf jeder Ebene ein Problem, eine enge Kopplung nicht zu erkennen und geeignete Abstraktionen zu erzeugen. Das Üben dieser Fähigkeiten in C, bis Sie einen Algorithmus erstellen können, der sauber und lesbar aussieht, überträgt sich auf jede Sprache, die Sie verwenden.

Das andere Problem, das ich gelegentlich bei Python-Programmierern sehe, ist die Schwierigkeit, sich an die Leistung im Maßstab anzupassen. Zugegeben, Leistung ist normalerweise nicht das Hauptanliegen, aber die pythonischste Methode zum Implementieren eines Algorithmus für eine relativ kleine Datenstruktur kann Ihr System zum Stillstand bringen, wenn Sie mit Gigabyte oder mehr Daten arbeiten. Wenn Sie ein guter C-Programmierer sind, sind Sie sich dieser Probleme in jeder Sprache bewusster.

Können Sie diese Fähigkeiten in anderen Sprachen lernen? Sicher, aber C hilft, indem es es viel offensichtlicher macht, wenn Sie es falsch verstehen.

Abgesehen davon verwende ich Python für die algorithmische Programmierung, wenn ich die Wahl habe, obwohl ich mich in C genauso wohl fühle. Python verfügt über Sprachfunktionen, die es für diese Art der Programmierung sehr gut machen, und Leistungsunterschiede sind normalerweise vernachlässigbar. Ich kann nicht darüber sprechen, warum andere Programmierer, die beide kennen, C wählen würden. Ich stelle mir vor, dass viele von ihnen es einfach tun, um sich von der Masse abzuheben.

Karl Bielefeldt
quelle
1
"Sie sind es zu gewohnt, sich diese Abstraktionen zur Verfügung stellen zu lassen." Geht das davon aus, dass ich Python vor C gelernt habe und mich daher nicht anpassen kann oder so?
ffledgling
10

Forscher, deren Hauptinteresse nicht in der Programmierung liegt, bevorzugen höhere Programmiersprachen wie Python, da sie eine Lösung in solchen Sprachen leichter codieren können als beispielsweise C. Python ist dafür besonders gut geeignet, da es eher auf "Prototyping" ausgerichtet ist "Batterien enthalten", und es lässt sich in numerische Bibliotheken wie NumPy und SciPy integrieren.

Wenn ein Forscher eine bessere Leistung benötigt, übergibt er den in Python erstellten Algorithmus in der Regel an einen Software-Ingenieur, der Möglichkeiten zur Optimierung findet (bis zu und einschließlich der Neucodierung in C).

Robert Harvey
quelle
Im Grunde genommen haben Forscher und Softwareingenieure eine Designer-Handwerker-Beziehung? Und was ist mit der Nutzung beider Arten von Menschen in der Branche?
ffledgling
9
Ich denke, dass das Codieren eines Algorithmus in Python und das anschließende Schreiben einer verfeinerten Implementierung in C ein durchaus akzeptables Szenario ist.
Robert Harvey
oder "umkodieren in Cython"?
Endolith
10

Denken Sie daran, dass SPOJ.pl, der ACM-Wettbewerb und alle ähnlichen Wettbewerbe darauf ausgerichtet sind, schnell funktionierenden Code zu erstellen, der gleich nach dem Wettbewerb weggeworfen wird. TopCoder tut dies, jedoch in geringerem Umfang (Code ist zumindest auf der OO-Design-Ebene ordnungsgemäß organisiert).

In der realen Welt des Programmierens ist jedoch fast jede Abkürzung, die Sie in Wettbewerben zur algorithmischen Programmierung verwenden, ein Anti-Pattern. Nur wenn Sie dies berücksichtigen, können Sie Vergleiche anstellen. Nehmen wir ein Beispiel: Sie übergeben ein mehrdimensionales Array zwischen verschiedenen Funktionen. In einem Wettbewerbsumfeld ist es am besten, das Array einfach als global zu deklarieren, um Zeit bei der Ermittlung der richtigen Anrufdetails zu sparen (z. B. sollte ich die Größe übergeben oder kann sie bestimmt werden?). In der realen Programmierung würde ich genau das Gegenteil tun.

Also, zu Ihrer Frage, gibt es irgendwelche komplexen Konsequenzen, wenn Sie Python anstelle von C für Algorithmen wählen, ich würde nein sagen. Wenn Sie sich nur für den Algorithmus interessieren, gehen Sie in Python und C genauso vor. Die Implementierung in einer funktionalen Sprache kann einige Unterschiede nach sich ziehen, der Algorithmus ist jedoch immer noch derselbe.

Praktisch das einzige, was Sie durch die Implementierung des Algorithmus in C erreicht haben, ist eine bessere Kontrolle über die Ausführung und die Garantie, dass Sie nur Abstraktionen auf niedrigerer Ebene verwenden. Dies ist keine Kleinigkeit, da in Python ein Großteil der Komplexität verborgen ist. Aber wenn das Problem in den übergeordneten Abstraktionen nicht trivial ist, haben Sie möglicherweise nur an Ausführungsgeschwindigkeit verloren, und in den meisten Fällen versuchen Sie nicht wirklich, das Programm so schnell wie möglich zu machen. Sie lernen einfach .

Wie bereits vorgeschlagen, können Sie eine Python-Implementierung immer durch eine C-Implementierung ersetzen, wenn sich herausstellt, dass Python zu langsam ist. In einem großen Projekt wird dies jedoch wahrscheinlich zwei- bis dreimal vorkommen. Daher ist das Starten in C möglicherweise Zeitverschwendung, es sei denn, es ist die Sprache Ihrer Wahl (und Sie haben angegeben, dass dies nicht der Fall ist).

K.Steff
quelle
1
Wenn man eine echte mathematikintensive Anwendung schreibt, wählt man mit ziemlicher Sicherheit C oder C ++ (es gibt kein C / C ++), da die Leistung gegenüber jeder interpretierten Sprache enorm zunimmt. Ich habe mir Topcoder vor ein paar Jahren angeschaut und ich erinnere mich, dass ich eine Menge C ++ gesehen habe, die nur so viel Speicher verloren haben, weil die Wettbewerbe sich nicht um kleine Details wie Lecks gekümmert haben. Ich war nicht beeindruckt.
Jim In Texas
Genau mein Punkt. Es ist eine Frage der Prioritäten: Topcoder kümmern sich nicht um Speicherlecks, da der Kernel ohnehin nach ihnen bereinigen wird; Sie interessieren sich nicht für schlechte Praktiken oder Anti-Muster, wenn sie Zeit sparen.
K.Steff
2
Ihr letzter Absatz verkörpert die goldene Regel: "Lass es funktionieren, dann mach es schnell".
Carson63000
9

Als langjähriges Mitglied von TopCoder und gelegentlicher Benutzer von SPOJ kann ich Ihnen sagen, dass ein Hauptgrund für den Vorzug von C / C ++ gegenüber anderen Sprachen in Wettbewerben die Geschwindigkeit ist. Wenn Ihre Programmausführung zeitgesteuert ist, besteht ein enormer Druck, die "schnellste" Sprache auszuwählen, die Sie bekommen können, da Sie dadurch mehr Zeit für die Codierung Ihres Algorithmus haben. Mein Aufstieg in TC ging von Java über C # nach C ++.

Diese Situation ist jedoch bei Wettbewerben häufiger anzutreffen als bei der täglichen Entwicklung: Obwohl das Schreiben von optimalem Code von allgemeiner Bedeutung ist, ist die relative Bedeutung, Ihren Code so schnell wie möglich fertigzustellen und so wartbar wie möglich zu machen, in der Regel wichtiger als das Sparen einiger weniger hundert CPU-Zyklen. Wenn Sie etwas in Python besser programmieren können, ist dies häufig eine bevorzugte Lösung.

Darüber hinaus bietet Python Funktionen auf hoher Ebene, die in C ++ nicht verfügbar sind. Das Erstellen ist oft sehr teuer und manchmal sogar unmöglich (z. B. sollten Sie Überlegungen anstellen oder sich selbst ändernden Code in C ++). In solchen Fällen kann sich auch die Verwendung einer höheren Sprache als optimale Lösung erweisen.

dasblinkenlight
quelle
Da Sie ein Benutzer von TC und SPOJ sind. Ist der Kompromiss zwischen Zeit und Einfachheit sehr groß, wenn wir Python für den Code verwenden? Dh ist es möglich, erfolgreiche Übermittlungen mit Python durchzuführen, wenn derselbe Algorithmus mit C erfolgreich übermittelt werden kann? (Ja , ich weiß , es wird / könnte stark Frage zu Frage variieren , wird aber ein dis-Vorteil in den meisten Fällen sein oder nur einige?)
ffledgling
@ Ayos Ich kann nicht für Python sprechen, weil ich es nie im Kontext von TC oder SPOJ verwendet habe, aber der Vorteil von C ++ gegenüber C # und Java ist nur gelegentlich wichtig, und selbst dann ist er nicht übermäßig bedeutend. Ich kann mich nur an einen Fall erinnern, in dem ein unkomplizierter Port eines Algorithmus, der in C ++ in C # codiert wurde, mit einer Zeitüberschreitung fehlgeschlagen ist, sich jedoch in einem Übungsraum befand. Meistens ist das Ermitteln des richtigen Algorithmus das einzige, was den Unterschied zwischen erfolgreichen und fehlgeschlagenen Übermittlungen ausmacht.
dasblinkenlight
1
Beachten Sie, dass interpretierte Sprachen wie Python, Ruby und Perl um ein Vielfaches langsamer ausgeführt werden als kompilierte Hochsprachen wie Java und C # (die selbst im Vergleich zu C langsam sind). Letztendlich spielt es jedoch keine Rolle, wenn Sie nicht vorhaben, mit außergewöhnlich großen Datenmengen zu arbeiten oder Echtzeitgeschwindigkeit benötigen.
KChaloux
5

Jedes Mal, wenn ich mich hinsetze, um einen Code in C zu schreiben, gebe ich nach etwa 15 Minuten auf, weil ich es zu umständlich finde und dazu neige, zu Python überzugehen.

Dieser Produktivitätsgewinn ist der häufigste Grund dafür, dass C- und C ++ - Jobs erheblich abgenommen haben.

Dies ist eine Frage darüber, wie sich diese spezielle Praxis, Python wegen der Benutzerfreundlichkeit C vorzuziehen, auf lange Sicht auf mich oder einen anderen Programmierer / Informatiker auswirken wird.

Hierzu gibt es zwei Kernteile. Die erste ist die algortihmische Programmierung. Es ist wirklich egal, in welcher Sprache Sie den Algorithmus ausdrücken. Die Arbeit mit dem Algorithmus selbst und das Einpassen der richtigen in die richtigen Probleme sind die Schlüsselelemente, daher gibt es dort kein wirkliches Problem.

Der zweite Teil betrifft Produktivitätssteigerungen. Es ist eine gute Gewohnheit, Dinge zu verwenden, die Sie mit der Zeit produktiver machen, und die Ihnen während Ihrer Karriere nur Vorteile bringen. Es ist sehr hilfreich, die Algorithmen in verschiedenen Sprachen ausdrücken zu können, aber diese Hilfsbereitschaft hängt mehr davon ab, welche Redewendungen die Sprachen verwenden, und nicht unbedingt davon, was diese Sprachen sind.

Kurz gesagt, mach dir keine Sorgen . Was Sie verwenden, um den Algorithmus auszudrücken, ist weit weniger wichtig, als ihn überhaupt ausdrücken zu können.

Telastyn
quelle
3
Msgstr "C - und C ++ - Jobs haben erheblich abgenommen". Huh? Dies scheint aus heiterem Himmel zu sein, da ich den entgegengesetzten Trend sehe. -1, bis Sie eine Quelle für diese Anweisung angeben können.
3

Die Vorteile der Verwendung übergeordneter Sprachen wie Python oder Ruby liegen darin, dass (1) ihre Syntax dem Pseudocode sehr nahe kommt und (2) ihre Standardbibliotheken sofort nützliche Datenstrukturen bereitstellen (das von @Robert erwähnte Konzept der mitgelieferten Batterien). Es ist also vollkommen in Ordnung, sie vorzuziehen. Verwenden Sie, was auch immer Ihre Produktivität maximiert, anstatt eine Sprache auszuwählen, nur weil sie Mainstream oder "cool" ist.

Sakisk
quelle
Bist du ein Hipster oder so? Hier ist dein Züchterrecht. Mir? Ich wäre lieber cool.
Thomas Eding
2

Was Sie beim Programmieren in "höheren" Sprachen als C / C ++ verpassen werden, ist zu lernen, wie Computer funktionieren. Sie können keine eingebetteten Systeme, Betriebssysteme und Hardwaretreiber entwickeln. Das Kennen von C hilft auch beim Erlernen von Assembler.

Außerdem wird die überwiegende Mehrheit aller unternehmenskritischen Systeme immer noch in C entwickelt, sodass Sie möglicherweise nicht in der Lage sind, in mehreren Software-Software-Branchen (Luft- und Raumfahrt / Automobilindustrie / Medizintechnik usw.) zu arbeiten, ohne dies zu wissen.


quelle
Es ging explizit um Algorithmen, nicht um metallnahe Aspekte.
Konrad Rudolph
@KonradRudolph Nun gut, aber das Schreiben von Hardwaretreibern hängt meistens sehr eng mit Algorithmen zusammen. Wenn Sie beispielsweise einen Treiber für einen Analog-Digital-Wandler schreiben, müssen Sie digitale Filter und möglicherweise auch eine Art Warteschlangen- oder Prioritätssystem entwickeln. Und dann eine API über Ihrem Treiber. Es ist sehr ähnlich dem Schreiben eines "Objekts" oder "abstrakten Datentyps".
@Lundin Danke für die Erwähnung der Nachteile im realen Szenario.
ffledgling
1

Wenn jemals eine Frage zur 'Big O'-Notation gestellt wird und Sie versuchen, dies zu messen, kann es schwieriger sein, dies in Python zu tun, es sei denn, Sie wissen viel mehr darüber, wie Python Dinge implementiert, zum Beispiel, dass eine Python-Liste keine verknüpfte Liste ist ; Pythons sort ist TimSort; Python Müll sammelt zu bestimmten Zeiten ...

Ich finde es immer einfacher, ein C-Programm mit dem zu verbinden, was wahrscheinlich auf einem Prozessor geschieht, aber selbst hier gibt es Prozessor-Caching. Time-Slicing des Betriebssystems; Compiler-Optimierungen usw., die sich auf meine Intuition auswirken können.

Ich finde es schneller, Python-Code zu schreiben und zu debuggen. Wenn ich also die Wahl habe, schreibe ich zuerst in Python und konzentriere mich darauf, dass etwas funktioniert. Mit diesem funktionierenden Python-Programm können Sie es häufig in ein größeres System einbinden und nicht nur feststellen, dass es funktioniert hat, sondern auch, ob es schnell genug war oder in welcher Hinsicht es langsam war. Das Abrufen realer Leistungsdaten hilft dann bei der Optimierung der Geschwindigkeit und ermöglicht das Testen der Python-Version gegen spätere Neuschreibungen in Python oder C oder was auch immer.

Die Verwendung von Python hat also den Nachteil, dass es schwierig sein kann, die Vorteile von Algorithmen zu nutzen, die in Erwartung einer C-ähnlichen Kompilierung für das Prozessormodell geschrieben wurden. Die Nachteile der Verwendung von nur C sind, wie Sie angegeben haben: Es ist ein Schwein, das Sie schreiben und debuggen müssen, und Sie müssen am Ende zu oft Ihre eigenen Bibliotheken schreiben.

Ich denke, es wäre am besten, sie beide (und andere Sprachen) zu verwenden, bis Sie ein Gefühl für ihre Kompromisse bekommen. Ich selbst war ein guter C-Codierer, aber jetzt schreibe ich sehr wenig ursprünglichen C-Code, obwohl ich in meiner Arbeit immer noch C-Code lesen (und manchmal debuggen) muss. Obwohl ich Python bevorzuge, kenne und benutze ich Perl und Awk (und sed und grep und sort und Tcl und C und ...).

Paddy3118
quelle
Ich bin mit dem ersten Absatz nicht einverstanden. Python legt großen Wert auf Datenstrukturen und dokumentiert klar, wie die vordefinierten Datenstrukturen implementiert werden. Natürlich wird die Garbage Collection die Laufzeiten verzerren, aber die Big-O-Order wird selten verzerrt.
Konrad Rudolph
1

Ich würde Ihnen raten, sich Scala oder Clojure anzuschauen (aber schreiben Sie Anmerkungen). In einigen Fällen können sie so schnell sein wie C, in anderen Fällen sind sie noch viel schneller als Ruby / Python, während sie im Gegensatz zu C ( IMHO ) eine sehr konsistente und klare Notation haben . Betrachten Sie diesen vs C-Code:

for (i <- 1 to 100; j <- 2 until 100;
     k <- 1 to 2; if i != j) {
     //...
}

Auch sie haben Funktion Programmierung Arsenal ähnlich wie Ruby / Python map, filter, reduceetc. das ist nicht so schnell wie das Iterieren oder Endrekursion Rekursion, aber es ist noch viel schneller ist dann die voll dynamischen Skriptsprachen.

defhlt
quelle
1

Ich würde gerne von Leuten hören, die diese Sprachen in der Industrie verwendet haben / und oder große Software / Bibliotheken usw. entwickeln.

Ich habe einige Jahre an einem kleinen Teil einer großen C ++ - Bibliothek gearbeitet und sowohl meine Bachelor- als auch meine Masterarbeit im Kontext dieser Bibliothek geschrieben. Die Bibliothek ist übrigens eine Bibliothek für bioinformatische Algorithmen und Datenstrukturen.

Die Bibliothek wurde in C ++ erstellt, da C ++ für die spezifischen Anforderungen dieser Bibliothek und für Algorithmusbibliotheken im Allgemeinen nahezu perfekt ist. Wenn ich eine andere Algorithmusbibliothek entwickeln würde und die Wahl der Sprache meine wäre, würde ich mit ziemlicher Sicherheit wieder C ++ wählen.

Der Grund ist nicht nur die Leistung, sondern auch das starke Schriftsystem, das Ihnen in erster Linie mehr Schriftsicherheit und in zweiter Linie die Möglichkeit gibt, den verwendeten Algorithmus von Ihren Schriften dokumentieren zu lassen . Dies kann (meiner Erfahrung nach) die Lesbarkeit und Wartbarkeit erheblich verbessern.

Für einfache algorithmische Kritzeleien und Rätsel verwende ich fast immer Python (hauptsächlich, weil es ja fast wie Pseudo-Code liest), es sei denn, ich möchte speziell ausprobieren, wie ein Problem in C ++ am besten formuliert werden kann. Bisher habe ich viele der SPOJ- oder TopCoder-Probleme nicht gelöst, daher weiß ich nicht, ob die Leistung dort wirklich so kritisch ist, dass die Verwendung einer schnellen Sprache von entscheidender Bedeutung ist.

Aber normalerweise zählt es, den Algorithmus richtig zu machen, um zu bestehen. In diesen Fällen funktioniert Python einwandfrei. Zum Beispiel ist Python für die Project Euler-Probleme (die nicht zeitlich festgelegt sind, sondern nur die richtige Lösung) perfekt geeignet.

Konrad Rudolph
quelle