Ist es üblich, keine Bibliotheken für numerische Standardalgorithmen zu verwenden, und warum?

54

Zahlreiche numerische Algorithmen (Integration, Differenzierung, Interpolation, Sonderfunktionen usw.) sind in wissenschaftlichen Berechnungsbibliotheken wie GSL verfügbar . Aber ich sehe oft Code mit "handgerollten" Implementierungen dieser Funktionen. Ist es bei kleinen Programmen, die nicht unbedingt für die öffentliche Verbreitung bestimmt sind, unter Computerwissenschaftlern üblich, nur selbst numerische Algorithmen zu implementieren (dh von einer Website, numerischen Rezepten oder ähnlichem zu kopieren oder zu transkribieren), wenn Sie diese benötigen? Wenn ja, gibt es einen bestimmten Grund, die Verlinkung mit so etwas wie GSL zu vermeiden , oder ist es eher "Tradition" als irgendetwas anderes?

Ich frage, weil ich ein großer Fan der Wiederverwendung von Code bin , was nahelegt, dass ich versuchen sollte, vorhandene Implementierungen zu verwenden, wenn dies möglich ist. Aber ich bin neugierig, ob es Gründe gibt, warum dieses Prinzip beim wissenschaftlichen Rechnen weniger wert ist als beim allgemeinen Programmieren.


Vergessen zu erwähnen: Ich frage speziell nach C und C ++, im Gegensatz zu Sprachen wie Python, bei denen die Verwendung einer Bibliothek einen klaren Vorteil (Geschwindigkeit der Ausführung) hat.

David Z
quelle
14
Einerseits möchten Sie das Rad nicht neu erfinden. Auf der anderen Seite ist der Versuch, eine Implementierung selbst zu codieren, der beste Weg, um einen Algorithmus zu verstehen (und Fälle, in denen der Algorithmus spektakulär ausfällt, zu diagnostizieren).
JM
2
Tadeln Sie jeden Satz, dem Sie begegnen? Vielleicht probierst du es aus und spielst mit ein paar Baby-Hüllen herum, aber wenn es nicht der Schwerpunkt deiner Forschung ist, akzeptierst du es wahrscheinlich und gehst mit dem Leben weiter.
dls
3
Physiker sind keine Programmierer und sie sind es nicht gewohnt, mit dem Code anderer umzugehen (ihn zu lesen oder zu reparieren). Wenn sie den Code anderer verwenden müssen, ist es oft nicht gut geschriebener oder gut kommentierter Code, der von anderen Physikern geschrieben wurde, was wiederum die Idee verstärkt, dass es besser ist, ihn neu zu schreiben, als ihn wiederzuverwenden. Dies gilt zumindest in einigen Bereichen / Gemeinden, aber die Einstellungen der jüngeren Menschen ändern sich. Es ist jedoch nicht alles schlecht, denken Sie an die Haltung des schlechten CS-Schülers, der etwas nicht tun kann, wenn er keine Bibliothek findet, die einfach genug ist.
Szabolcs

Antworten:

45

Früher habe ich alles selbst implementiert, aber in letzter Zeit habe ich viel mehr Bibliotheken verwendet. Ich denke, es gibt einige sehr wichtige Vorteile der Verwendung einer Bibliothek, die über die Frage hinausgehen, ob Sie selbst eine Routine schreiben müssen oder nicht. Wenn Sie eine Bibliothek verwenden, erhalten Sie

  • Code, der von Hunderten / Tausenden / mehr Benutzern getestet wurde
  • Code, der auch in Zukunft ohne Ihr Zutun aktualisiert und verbessert wird
  • Optimierter Code, der effizienter und möglicherweise skalierbarer ist als das, was Sie beim ersten Versuch geschrieben haben
  • Abhängig von der Bibliothek können Sie durch Einrichten einer Schnittstelle in Ihrem Code auf viele Algorithmen zugreifen, die Sie derzeit nicht verwenden, aber möglicherweise in Zukunft verwenden möchten

Im letzten Punkt oben denke ich an große Bibliotheken wie Trilinos oder PETSc . Dies kann ich mit einigen konkreten persönlichen Beispielen in der Entwicklung von PyClaw untermauern . Obwohl es einfach gewesen wäre, Clawpack mit MPI-Aufrufen zu parallelisieren , haben wir uns für PETSc entschieden. Auf diese Weise konnten wir den Paralle-Code im Paket auf weniger als 300 Zeilen Python beschränken. Durch das Versetzen unserer Daten in das PETSc-Format erhielten wir jedoch sofort Zugriff auf die impliziten Löser von PETSc, was die aktuelle Arbeit an einem impliziten Löser in PyClaw ermöglichte. Als zweites Beispiel enthielt PyClaw anfänglich eine WENO-Rekonstruktion fünfter Ordnung mit Handcode, aber wir entschieden uns schließlich, uns auf PyWENO zu verlassenPaket dafür. Dies war ein großer Vorteil, da PyWENO automatisch WENO-Routinen in beliebiger Reihenfolge in mehreren Sprachen generieren kann.

Wenn Sie Bibliotheken verwenden, können Sie einen Beitrag leisten, indem Sie Verbesserungen entwickeln oder Fehler finden, von denen viele andere profitieren, während das Debuggen oder Verbessern Ihres eigenen Codes nur Ihnen zugute kommt.

David Ketcheson
quelle
5
"Sie können einen Beitrag leisten, indem Sie Verbesserungen entwickeln oder Fehler finden, von denen viele andere Menschen profitieren." - das würde sowohl den "Bastel- / Lerndrang" als auch die Faulheit befriedigen (Dinge nicht tun müssen, die bereits getan wurden). :)
JM
1
Siehe auch Kantenfälle. Für viele Algorithmen ist es trivial, etwas zu implementieren, das "funktioniert", aber einige winzige Teilfälle nicht richtig behandelt. Dies mag für ein einmaliges kleines Projekt in Ordnung sein, aber ich kann nicht zählen, wie oft ich von pathologischen Zuständen an etwas "optimiert" wurde.
meawoppl
34

Das Verknüpfen mit einer Bibliotheksfunktion ist mit einem erheblichen Programmieraufwand verbunden, insbesondere wenn diese Bibliothek für den Programmierer neu ist. Es ist oft einfacher, einfache Algorithmen neu zu schreiben, als die Besonderheiten einer bestimmten Bibliothek herauszufinden. Wenn die Algorithmen komplexer werden, ändert sich dieses Verhalten.

Python konnte diesen Overhead mit Tools wie pip / easy_install und einer einheitlichen Datenstrukturschnittstelle (dh, jede Bibliothek scheint ein numpy-Array zu nehmen und zu produzieren) hervorragend reduzieren.

MRocklin
quelle
19

Eines der Projekte, an denen ich gerade beteiligt bin, ist das Schreiben eines flexiblen Simulations- und Analysepakets für eine Klasse von Detektoren der Teilchenphysik. Eines der Ziele dieses Projekts ist es, die Codebasis bereitzustellen, die in den kommenden Jahrzehnten in diesen Dingen verwendet werden soll.

Zu diesem Zeitpunkt haben wir bereits zwei Dutzend Abhängigkeiten, was den Erstellungsprozess zu einem solchen Albtraum macht, dass er ein separates Projekt ausgelöst hat, das vom Fermilab-Rechenzentrum aus verwaltet wird, um eine zuverlässige Toolkette bereitzustellen.

Stellen Sie sich nun vor, Sie brauchen ein Tool, das nicht in dieser Toolkette enthalten ist (mir ist es erst letzten Monat passiert). Sie haben drei Möglichkeiten

  1. Rolle dich selbst. Mit all den Risiken und Schwierigkeiten, die damit verbunden sind.
  2. Kratzen Sie irgendwo Code aus einer Bibliothek und fügen Sie ihn in The Project ein. Das bedeutet, dass Sie in Zukunft die Wartung übernehmen müssen und in diesem Fall den Code eines anderen Benutzers verstehen müssen.
  3. Gehen Sie zu den Leuten, die die Toolkette pflegen, bitten Sie sie um das, was Sie brauchen, und warten Sie dann auf einen Veröffentlichungszyklus, um es zu bekommen. Diese Leute sind ziemlich reaktionsschnell, aber Sie müssen die Argumente dafür vorbringen, ohne Code zu verwenden oder nachdem Sie (1) oder (2) ausgeführt haben.

Es ist sehr einfach zu wählen (1). Vielleicht zu einfach.

dmckee
quelle
Ja, hinzugefügte Abhängigkeiten sind ein wesentlicher Nachteil bei der Verwendung von Bibliotheken.
David Ketcheson
Abhängigkeiten ist der große Nachteil in meinem Kopf auch
Fomite
2
Es ist möglich, dass meine Antwort zu viel Gewicht auf die Tatsache von Abhängigkeiten legt und nicht genug auf den bürokratischen Prozess, in großen Projekten genehmigte Anzeigen für Abhängigkeiten zu installieren.
dmckee
* Ihr in Punkt 3. (Entschuldigung für den Nitpick.)
299792458
Äh ... nein. Es sagt, was ich meine.
dmckee
12

Ich denke, es ist ziemlich üblich, dass einige Algorithmen eher reimplementiert werden als andere.

Es gibt einen kniffligen Kompromiss zwischen der lästigen Installation einer Bibliothek, der Schwierigkeit, den Algorithmus selbst zu implementieren, der Schwierigkeit, ihn zu optimieren und der Anpassung der Bibliothek an Ihre Anforderungen. Manchmal ist die Verwendung einer Bibliothek einfach zu viel: Ich habe in einem meiner Programme den langsamen Halbierungsalgorithmus verwendet, weil ich ihn nur ein paar Mal aufgerufen habe und deshalb keine Bibliothek hinzufügen wollte.

Ist es für Sie einfach, eine gut optimierte Version zu schreiben? Wenn ja, ist es vielleicht besser für Sie. Sie bekommen genau das, was Sie brauchen und sind nicht auf die Arbeit anderer angewiesen. Aber natürlich müssen Sie wirklich wissen, was Sie tun: Selbst einfache Algorithmen können schwierig zu implementieren sein.

Ich wäre gespannt auf eine Studie dazu, aber aus meiner voreingenommenen Perspektive verwenden Wissenschaftler häufig Bibliotheken für lineare Algebra und Zufallszahlengeneratoren, wobei der größte Teil des verbleibenden Codes hausgemacht ist.

PhDP
quelle
12
"Aber natürlich müssen Sie wirklich wissen, was Sie tun: Selbst einfache Algorithmen können schwierig zu implementieren sein." - Dies kann nicht genug betont werden.
JM
10

Ich denke, dass die Implementierung eines Algorithmus anstelle der Verwendung einer Bibliothek manchmal zu einem besseren Verständnis und einer besseren Kontrolle des Modells führen kann. Wenn ich ein Programm für wissenschaftliche Berechnungen programmiere, ist es für mich wichtig zu verstehen, was ich tue. Die Implementierung der wichtigen Algorithmen hilft mir, das Problem besser zu kennen und besser zu kontrollieren.

Andererseits ist es manchmal keine einfache Aufgabe, eine Bibliothek auszuwählen, die zum Abrufen einer Lösung benötigt wird. Es ist daher besser, nach bereits implementierten Algorithmen zu suchen, wenn Sie sicher sind, was Sie erreichen möchten und warum Sie es möchten.

Wenn die Algorithmen komplex sind, haben Sie durch die manuelle Codierung die Möglichkeit, die Leistung / Qualität der Lösung mithilfe aufgabenspezifischer Funktionen zu verbessern. Und manchmal ist es notwendig, den Algorithmus ein wenig zu ändern. Dies ist einfacher, wenn Sie den von Ihnen geschriebenen Code kennen und ihn nach Ihren Wünschen bearbeiten können.

gmk
quelle
1
+1 zur Verbesserung des Verständnisses. Dies ist jedoch eher ein Problem für Ihre eigenen Algorithmen als für eine Bibliotheksroutine.
Faheem Mitha
8

Eine Antwort ist, dass es so viele geringfügige Variationen des numerischen Codes gibt, dass es wirklich schwierig ist, dies in einer Bibliothek zu kapseln. Nehmen Sie dies im Vergleich zu Web-Software, die oft einfach zu installieren ist und eine klare Reihe von Ein- und Ausgängen hat. Ich denke, häufiger greifen Leute nach einem Framework oder einer großen Bibliothek, die wie ein Framework fungiert (Trilinos / PETSc), und nutzen dieses Ökosystem, um die Vorteile der Verwendung von Community-Codes zu nutzen.

aterrel
quelle
7

Bevor Sie entscheiden, ob Sie Bibliotheken verwenden möchten oder nicht, sollten Sie auch herausfinden, inwieweit die Verwendung einer Bibliothek Ihrem Code hilft. Wenn Sie eine gut optimierte Bibliothek für einen wichtigen Rechenkern verwenden, ist dies wahrscheinlich weitaus effizienter als der Versuch, eine eigene Bibliothek zu schreiben.

Wenn Sie jedoch eine spezielle Routine schreiben, die während der Ausführung eines Programms nur einmal aufgerufen wird, lohnt es sich möglicherweise nicht, den Code an das für eine Bibliothek erforderliche Framework anzupassen.

(Eine weitere Überlegung: Wie viel Umbau müssen Sie tun, um die Bibliothek zu nutzen? Sofern die für die Korrektur des Codes aufgewendeten Arbeitsstunden nicht durch entsprechende Effizienz- oder Genauigkeitsgewinne ausgeglichen werden, ist dies möglicherweise nicht der Fall Auf lange Sicht lohnt sich das. Idealerweise planen Sie dies jedoch, wenn Sie zunächst Datenstrukturen und Algorithmen entwerfen, damit der "Fluss" der Bibliothek von Grund auf berücksichtigt wird.)

Aeismail
quelle
6

Meine 2 Cent.

Ich denke, es ist einfacher, allgemein darüber zu schreiben, als nur über C / C ++. Erstens werden Bibliotheken in Sprachen wie Python nicht unbedingt verwendet, um einen Geschwindigkeitsvorteil zu erzielen, auch wenn dies eine Konsequenz ist. Ich denke, @David hat die Gründe ziemlich gut dargelegt .

Von oben betrachtet, bestimmt die Sprachimplementierung in gewissem Maße, auf welche Bibliotheken Sie zugreifen können. Zu den in der Computerwissenschaft am häufigsten verwendeten Sprachen gehören C, C ++, Python, Perl, Java, Fortran und R. Weniger häufig verwendete Beispiele sind Ocaml und Common Lisp. Da die meisten dieser Sprachen in C geschrieben sind, haben sie eine natürliche Fremdfunktionsschnittstelle zu C. Es ist jedoch nicht so einfach, beispielsweise eine Perl-Bibliothek aus Python oder umgekehrt aufzurufen. In der Praxis neigen die Leute also dazu, entweder

  1. Verwenden Sie eine Bibliothek, die in ihrer Implementierungssprache geschrieben ist, normalerweise als Teil der Standardbibliotheken oder auf andere Weise allgemein verfügbar

  2. Rufen Sie eine C / C ++ - Bibliothek über die Sprachen FFI auf. Dies setzt voraus, dass ein Wrapper noch nicht existiert, da er sonst nicht leicht von (1) zu unterscheiden ist.

(2) ist normalerweise schwieriger, da Sie die C / C ++ - Funktion selbst umbrechen müssen. Außerdem müssen Sie entweder die Bibliothek bündeln oder eine zusätzliche Abhängigkeit hinzufügen. Aus diesem Grund verwenden Benutzer eher die integrierten Sprachbibliotheken als beispielsweise GSL (in C).

Bei sehr generischen Routinen, z. B. der Erzeugung von Zufallsstichproben aus Verteilungen oder grundlegenden numerischen Routinen wie der Quadratur von Integralen, ist es einfach und üblich, einige Bibliotheken wiederzuverwenden. Da die Funktionalität, die Sie implementieren möchten, immer komplexer wird, wird es exponentiell unwahrscheinlicher, dass Sie genau die gewünschte Funktion in einer anderen Bibliothek finden, und selbst wenn Sie dies tun, können Sie viel Zeit damit verbringen, die Funktion zu suchen und schließlich anzupassen notwendig (der Code-Stil / Design könnte zum Beispiel ein Problem sein). Und wie oben diskutiert, hat man Zugriff auf nur eine Teilmenge der Bibliotheken da draußen. Andererseits kann es entmutigend sein, einen Algorithmus selbst zu implementieren, wenn er komplex ist und nicht das Hauptaugenmerk liegt, und natürlich muss man sich mit diesen lästigen Geschwindigkeitsproblemen befassen.

Dies wird zu einem Optimierungsproblem bei der Kosten-Nutzen-Analyse. Ich habe die Erfahrung gemacht, dass ich selbst für vergleichsweise Standardtechniken wie MCMC in der Regel meinen eigenen Code schreibe, weil er besser zu der Art und Weise passt, wie ich die gesamte Software entwerfe.

Selbst wenn Sie den Code am Ende nicht verwenden, können Sie natürlich auch aus dem Code anderer lernen. Ich weiß allerdings nicht, wie oft sich Wissenschaftler tatsächlich die Mühe machen, dies zu tun. Mein Eindruck ist, dass das Lesen des Codes anderer Leute eher eine Sache des Software-Ingenieurs ist.

Faheem Mitha
quelle
6

Wenn ich an meinen Mechanikkurs im zweiten Jahr zurückdenke, fällt mir ein, dass ein Teil der Gründe, warum ich meine eigenen Versionen bekannter Algorithmen implementiert habe, darin besteht, dass mir beigebracht wurde, dies auf diese Weise zu tun. Ich kann mir kein einziges Beispiel vorstellen, in dem mir beigebracht wurde, wie man in meiner Grundausbildung in Physik eine Schnittstelle zu einer Bibliothek herstellt und diese damit verbindet. Ich kann mich gut daran erinnern, dass ich zum ersten Mal eine Liste der Koordinaten eines sich drehenden Golfballs gesehen habe, nachdem ich die Lösung der gekoppelten Newton-Gleichungen in FORTRAN selbst berechnet habe. Es gibt einen gewissen Nervenkitzel und eine gewisse Befriedigung (sogar einen gewissen Stolz), wenn Dinge von Grund auf neu berechnet werden.

JxB
quelle
1
Dies ist sicherlich ein Faktor. Und diese Konzentration auf das Selbermachen ist für einen Teil der Ausbildung eines Informatikers erforderlich. Die reinen Programmierer werden irgendwann davon abgehalten, aber wir Wissenschaftstypen können direkt von diesem einführenden Klassenzimmer in ein Projekt übergehen, das fast ausschließlich von anderen Leuten bevölkert wird, die auf dem gleichen Weg kamen.
dmckee
5

Ich denke, man sollte so oft wie möglich getestete Bibliotheken verwenden. Die meisten Leute sind keine Experten für numerisches Rechnen und werden wahrscheinlich nicht in der Lage sein, eine Lösung so korrekt und sorgfältig zu implementieren, wie es in gut getesteten Bibliotheken verfügbar ist. Gelegentlich gibt es jedoch keine verfügbaren Bibliotheken, die die in einer bestimmten Anwendung erforderliche Kombination von Funktionen implementieren. Ich habe dies in dem technischen Bereich gesehen, in dem ich arbeite. Bestehende Codes lösten nicht alle Fälle, und schließlich implementierte jemand einen Solver von Grund auf neu.

mhucka
quelle
1
Wenn die Bibliothek nicht alle Ihre Bedürfnisse abdeckt, würde ich empfehlen, den Bibliothekscode zu erweitern und einen Patch einzureichen. Auf diese Weise profitieren viele andere von Ihrer Arbeit, und andere testen Ihren Code auch für Sie. Dies setzt natürlich voraus, dass der Bibliothekscode so flexibel geschrieben wurde, dass er Ihren Anforderungen entsprechend erweitert werden kann.
David Ketcheson
Ich stimme zu, das ist eine großartige Lösung und etwas, das die Leute tun sollten, wenn es überhaupt möglich ist.
mhucka
5

Das grundlegende Problem liegt häufig in der Schnittstelle zwischen der Anwendung und der Bibliothek. Ein Anwendungsprogrammierer hat Kenntnisse über das Problem, die häufig verloren gehen, wenn das Problem (beispielsweise als Matrix) an eine Bibliothek übergeben wird. Dieses Wissen ist so beschaffen, dass es die Vorteile der Verwendung der hochoptimierten Bibliothek mehr als wettmacht. Infolgedessen "rollt" der Anwendungsprogrammierer seine / ihre eigene Implementierung, die das Wissen ausnutzt.

Daher muss eine wirklich gute Bibliothek dieses Wissen von der Anwendung an die Bibliothek weitergeben, damit auch die Bibliothek es nutzen kann.

Robert van de Geijn
quelle
3

Zusätzlich zu all dem, was oben bereits gesagt wurde, möchte ich meine Antwort auf die Frage "Fortran vs C ++" wiederholen: Das wertvollste Kapital, das eine Programmiererin hat, ist ihre Zeit. Ja, externe Abhängigkeiten sind oft umständlich. Es ist jedoch fast immer dumm, Zeit für die Neuimplementierung, das Debuggen und Testen von Algorithmen zu investieren, die bereits von anderen implementiert wurden, und das Ergebnis ist selten so gut wie Code, der von Experten zu einem bestimmten Thema geschrieben wurde. Verwenden Sie das, was andere getan haben, wieder!

Wolfgang Bangerth
quelle
Ich gebe meine eigene Antwort zu diesem Thema. Sie können viel mehr lernen, wenn Sie alle Details neu schreiben. Ich arbeite jetzt seit 5-6 Jahren mit Punktwolken. Die ersten drei Jahre habe ich alle Funktionalitäten selbst geschrieben. Die zweite Hälfte habe ich mit der Point Cloud Library verbracht. Ich kann es nicht beweisen, aber ich betrachte mich als stärkeren Experten für PCL, da ich die ersten drei Jahre damit verbracht habe, über Lösungen nachzudenken, die andere bereits angeboten haben.
Jan Hackenberg,
@JanHackenberg - ja, aber lassen Sie mich auch stumpf sein: Sie haben gerade drei Jahre Ihres Lebens damit verbracht, Räder neu zu erfinden. Stellen Sie sich vor, wie viel neues Zeug Sie hätten tun können, wenn Sie das verwendet hätten, was andere getan haben !?
Wolfgang Bangerth
Ich entschied mich, in meinem ersten Doktorjahr in Java zu schreiben, weil ich zu diesem Zeitpunkt meine Programmierkenntnisse (nicht die Theorie der Informatik) als nahe Null ansah. Java war immer noch die Sprache, die ich in der Praxis am besten beherrschte. Ich habe Java auch wegen der einfachen Unterstützung mehrerer Plattformen als gute Wahl angesehen. Ich betrat einen Lehrstuhl ohne informatische Unterstützung in der Doktorarbeit (traditionelle Forstwirtschaft). Ich bin zu c ++ gesprungen, als ich meinen Fehler erkannte und ich konnte (nach der Veröffentlichung, nicht vorher).
Jan Hackenberg
Übrigens bin ich nicht einverstanden mit den drei Jahren meines Lebens. Dies würde bedeuten, dass ich nur zwei nützliche Jahre Erfahrung in der Promotion nach der Promotion hatte. Heute kann ich 10 Milliarden Zylinder in eine forstwirtschaftliche Punktwolke einbauen und die Maschine entscheiden lassen, welche gut geeignet sind, Bäume darzustellen. Meine ~ 50 Benutzer können das auch. In ca. 1 Stunde. Alle Tricks, die ich gelernt habe, indem ich auf die harte und zeitraubende Weise gelernt habe. Ich habe mich entschieden, nie zu lernen, wie man vi benutzt, aber wenn Leute, die die erforderliche Lernkurve bestehen, behaupten, die effizienteste Methode zur Erzeugung von Code zu verwenden, glaube ich ihnen.
Jan Hackenberg
2

Die Gruppe, mit der ich zusammenarbeite, verwendet so oft wie möglich Bibliotheken. Ich bin einer der wenigen Programmierer, und der Rest der Leute hat das Programmieren bei der Arbeit aufgenommen. Sie wissen genug über ihre eigenen Grenzen, um zu wissen, wo sie sich nicht austoben sollten. IMSL ist die bevorzugte Bibliothek. Sachen wie GSL wären aus lizenzrechtlichen Gründen verboten, auch wenn dies eine Bundesbehörde ist und wir unsere Software trotzdem weitergeben.

Tangurena
quelle
2

"Die Wiederverwendung ist in erster Linie ein soziales Phänomen. Ich kann die Software eines anderen Benutzers verwenden, sofern dies der Fall ist

  1. Es klappt
  2. es ist verständlich
  3. es kann nebeneinander existieren
  4. es wird unterstützt (oder ich bin bereit, es selbst zu unterstützen, meistens nicht)
  5. es ist wirtschaftlich
  6. Ich finde es.

"- B. Stroustrup, The C ++ Programming Language 2 ed. (1991) S. 383.


quelle
1

Andere haben gute Gründe angegeben, Bibliotheken zu verwenden und eigene Routinen zu erstellen.

Manchmal können Sie die Berechnungen für eine bestimmte Anwendung beschleunigen, weil Sie im Voraus wissen, dass Sie niemals den großen Wertebereich, den die Bibliotheksroutine abdeckt, oder die Genauigkeit benötigen, die diese Routinen liefern.

Natürlich hängt vieles von der jeweiligen Anwendung ab und davon, wie oft die Bibliotheksroutine aufgerufen wird. Warum würden Sie eine Bibliotheksroutine für Bessel-Funktionen milliardenfach aufrufen, wenn Sie nur einige signifikante Zahlen für einen kleinen Bereich von x benötigen und eine einfachere Technik für Ihre Anforderungen ausreicht?

Lysistrata
quelle
0

Ist wenig hinzuzufügen, wir müssen Code wiederverwenden, es geht um Code-Nachhaltigkeit und einen Beitrag zur Gesellschaft, aber das ist alles oben.

Der Grund, warum wir Code nicht wiederverwenden, ist, dass es schwierig ist, anderen Code zu verstehen, wenn Sie mit dem Programmieren beginnen. Bei fortgeschrittenem C ++ ist dies besonders schwierig, und Sie können einige Tricks auch in reinem C ausführen.

Sehr oft versteht man zu Beginn die Methode, aber nicht, wie sie in der Bibliothek implementiert ist, oder einfach, wie man die Bibliothek mit ihrer generischen Schnittstelle, Fehlerkontrolle und Konventionen verwendet, die für erfahrene Programmierer sehr oft, wenn überhaupt, dokumentiert wird. Dies gibt die Illusion, dass es besser ist, eine Standardmethode wie die LU-Faktorisierung selbst zu implementieren. Darüber hinaus unterschätzen neue Programmierer den Wert von Code-Tests, Validierung und Portabilität für verschiedene Betriebssysteme. Der Grund dafür ist also Faulheit. Das Schreiben von eigenem Code scheint eine schnellere und einfachere Lösung zu sein.

Die Realität ist, dass wir durch das Verwenden und Lesen von Code mehr lernen können, als durch das Programmieren von Grund auf.

Faulheit treibt mich die meiste Zeit an, ich denke auch die Mehrheit der Menschen. Aus dem gleichen Grund schreiben einige Code von Grund auf neu und andere verwenden vorhandene Bibliotheken.

likask
quelle
-1

Bibliotheksalgorithmen bieten im Gegensatz zu eigenen Implementierungen:

  • Sie sind generisch und mit Vorlagen versehen. Sie können Ihre Implementierung später neu parametrisieren, ohne sich Sorgen machen zu müssen, dass Sie Ihren eigenen Code ändern müssen, der viele Einschränkungen haben sollte.
  • Es gibt Sicherheit gegen entartete Fälle von Eingabedaten. Viele Algorithmen zur Berechnung der Geometrie, z. B. solche mit konvexer Hülle, müssen beispielsweise die Kolinearität von drei Punkten verarbeiten. Sie können diese Fälle möglicherweise ignorieren, wenn Sie nie vorhaben, Ihren Code zu verbreiten, und Ihren Code auch in Zukunft nicht mehr häufig wiederverwenden möchten.
  • Sie bieten die minimale Laufzeitkomplexität für erwartete oder Worst-Case-Eingabekonfigurationen. Übergeordnete Algorithmen haben als Bausteine ​​häufig untergeordnete Algorithmen, z. B. Sortieralgorithmen oder spezielle Datentypen. Schnelles Sortieren ist möglicherweise die häufigste Methode zum Sortieren von Daten. Wenn Ihre Implementierung des Algorithmus jedoch n (log (n)) garantieren muss, können Sie ihn nicht verwenden.
  • Sie sind speichereffizient
  • Sie sind weiter laufzeitoptimiert
  • Wenn es unterstützt wird, ist es weitaus besser, generell "fehlerfrei" zu sein, besonders wenn Sie mit dem Hauptzweig arbeiten. Nichts ist erprobter als eine gut verteilte Bibliothek. Nicht jeder Fehler stürzt ab, nicht jeder Fehler führt zu unzumutbaren Ergebnissen. Die Implementierung Ihres Algorithmus führt möglicherweise immer noch zu akzeptablen Ergebnissen, die jedoch nicht so gut sind, wie sie vorgesehen sind. Je weniger ein Fehler sichtbar ist, desto unwahrscheinlicher ist es, dass Sie als Einzelperson ihn überhaupt erkennen können.

Ich halte es immer noch für gut, wenn Sie ein neues Feld eingeben, um eine Version eines gut verständlichen Algorithmus selbst zu implementieren. Insgesamt nehme ich mir viel Zeit. Ich kaufte und las Bücher, die genannten Press et al. Vor und während dieser Implementierungen habe ich immer viel Theorie gelesen. Und nachdem ich die allgemeinen Konzepte eines Feldes verstanden und die Fallen in der Praxis erlebt habe, ist es an der Zeit, zu den in allen Aspekten besseren Bibliotheksimplementierungen zu springen. Ich denke, Sie werden ein besserer Benutzer der Bibliothek, wenn Sie selbst einen "Hallo Welt" -Algorithmus im Bibliotheksbereich schreiben.

Wenn Sie in einem größeren Team arbeiten, ist es möglicherweise nicht Ihre eigene Wahl, ob Ihr Team eine bestimmte Bibliothek verwendet oder nicht. Das Kernteam könnte die Entscheidung treffen. Und es könnte eine Person geben, die für die Bindung der Bibliothek in Ihrem Projekt mit eigenen Zeitplänen verantwortlich ist. Umschreiben eines Algorithmus, den Sie mit Ihrer eigenen Zeitplanung durchführen können, ohne sich auf die Entscheidung anderer Personen verlassen zu müssen.

Wenn Sie alleine sind und gerne vertreiben, gibt es ein anderes Problem. Ich halte so gut wie viele andere Quellcodes für die nützlichste Ressource. Viele an alle Informatiker könnten hier zustimmen. In einem Anwendungsbereich außerhalb der Informatik kann es erforderlich sein, ein vorkompiliertes Programm für Windows bereitzustellen. Unter Linux können Sie bei Open Source-Verwendungsbibliotheken die Dinge relativ einfach selbst einrichten.

Das eigenständige Umschreiben eines Algorithmus gibt Ihnen die Freiheit, die Lizenz zu behalten. Ihr Projekt unterstützt beispielsweise möglicherweise nicht die GPL- Lizenz von GSL .

Die Lizenz könnte die einzige Einschränkung sein, die vom Standpunkt des Forschers unabhängig ist.

Jan Hackenberg
quelle
1
Es ist absurd zu glauben, dass "das Implementieren eines Algorithmus durch Sie selbst" und "das Erlernen der Bibliothekssyntax" "dieselbe Zeit kosten würde". Dies gilt nicht einmal für einfache Funktionen wie "strcat". Es ist definitiv nicht der Fall für alles, was beispielsweise in LAPACK oder in Bibliotheken höherer Ebene enthalten ist.
Wolfgang Bangerth
@WolfgangBangerth Danke für das Feedback. Ich habe noch einmal gelesen, was ich geschrieben habe, und wollte nicht die Botschaft übermitteln, dass eigene Implementierungen konkurrenzfähig sein können. Aber ich habe so viel gelernt. Mein "beide könnten zwei Wochen kosten" war kein gutes Beispiel. Tatsächlich hat mich das letzte "Erlernen der Syntax" 2 Wochen gekostet, als ich von Java auf C ++ umgestiegen bin und zu diesem Zeitpunkt auch die grundlegende C ++ - Syntax erlernt habe. Ich kämpfte mehr mit Zeigern als mit meiner neuen Bibliothek. Zwei Wochen für einen meiner implementierten Algorithmen waren möglicherweise Zeit für das Codieren, was meine geringe Investition war (das Lesen von Büchern dauert viel länger).
Jan Hackenberg
Die Investition besteht nicht darin, einen kleinen Algorithmus selbst zu schreiben. Das geht schnell und kann manchmal so lange dauern, bis man eine andere Bibliothek erlernt hat. Was unglaublich viel Zeit kostet, ist, Dinge zu debuggen und alle Eckfälle richtig zu machen. Wenn Sie eine gut entwickelte Bibliothek verwenden, wissen Sie, dass das Matrixvektorprodukt auch für rechteckige Matrizen funktioniert, wenn es für quadratische Matrizen funktioniert. Für Ihre eigene Software können Sie dies implementieren und debuggen, obwohl Sie dachten, Sie wären mit der Funktion fertig. Sie werden viele Male auf dieselbe Funktion zurückkommen. Das kostet Zeit.
Wolfgang Bangerth
@WolfgangBangerth Ich stimme allen Ihren Argumenten zu. Mein einziger Punkt ist, dass Sie viel mehr Theorie lernen, wenn Sie diese Eckfälle selbst behandeln müssen. Meine erste Version meiner Antwort klang tatsächlich so, als würde es keinen Unterschied machen. Ich war schrecklich müde. Ich schreibe in der verbesserten Antwort viel mehr über die Stabilitätsvorteile von Bibliotheken. Für mich ist es ein Kompromiss zwischen der aufgewendeten Zeit und dem erworbenen Wissen.
Jan Hackenberg