Was kann C ++ besser als D?


135

Ich habe kürzlich D gelernt und fange an, mich mit der Sprache vertraut zu machen. Ich weiß, was es bietet, ich weiß noch nicht, wie man alles benutzt, und ich weiß nicht viel über D-Redewendungen und so weiter, aber ich lerne.

Ich mag D. Es ist eine nette Sprache, die in gewisser Weise ein großes Update für C ist und gut gemacht wird. Keines der Features scheint "angeschraubt" zu sein, aber eigentlich recht durchdacht und durchdacht.

Sie werden oft hören, dass D das ist, was C ++ hätte sein sollen (ich überlasse die Frage, ob dies für jeden zutreffend ist, um unnötige Flammenkriege zu vermeiden). Ich habe auch von mehreren C ++ - Programmierern gehört, dass sie D viel mehr mögen als C ++.

Obwohl ich C kenne, kann ich nicht sagen, dass ich C ++ kenne. Ich möchte von jemandem hören , sowohl C zu wissen ++ und D , wenn sie denken , dass es etwas ist , das C ++ funktioniert besser als D als Sprache (was bedeutet , nicht die üblichen „es Bibliotheken von Drittanbietern hat“ oder „es gibt mehr Ressourcen“ oder " es gibt mehr Jobs, die C ++ erfordern als D ").

D wurde von einigen sehr erfahrenen C ++ - Programmierern ( Walter Bright und Andrei Alexandrescu , mit Hilfe der D-Community) entwickelt, um viele der Probleme, die C ++ hatte, zu beheben. Gab es jedoch etwas, das eigentlich nicht besser wurde? Etwas, das er verpasst hat? Etwas, von dem Sie denken, dass es keine bessere Lösung ist?

Beachten Sie auch, dass ich von D 2.0 spreche , nicht von D 1.0 .


15
Ich habe dafür gesorgt, dass die D-Community dies sieht, da es hier sicher weit mehr C ++ - Entwickler als D-Entwickler gibt. Auf diese Weise erhalten Sie interessantere oder zumindest abwechslungsreichere Antworten.
Fordern Sie den

7
Auch D2 wurde von Walter Bright entworfen, aber auch mit Alexandrescu. Vielleicht möchten Sie das in Ihrer Frage beheben.
Fordern Sie den

2
@Klaim: Es gab (und gibt immer noch) viel Community-Engagement in der D- und Standardbibliothek.
Michal Minich

28
@Anto Als Sprache ist C ++ viel besser als D, um Sie, den Programmierer, dazu zu bringen, Ihr Leben zu hassen.
Arlen

6
@jokoon: Eigentlich ja, mit sehr wenig Arbeit: digitalmars.com/d/2.0/interfaceToC.html
Anto

Antworten:


124

Die meisten Dinge, die C ++ besser macht als D, sind Meta-Dinge: C ++ hat bessere Compiler, bessere Tools, ausgereiftere Bibliotheken, mehr Bindungen, mehr Experten, mehr Tutorials usw. Grundsätzlich hat es mehr und besser von allen externen Dingen, die Sie haben würde von einer reiferen Sprache erwarten. Das ist unbestreitbar.

Was die Sprache selbst betrifft, gibt es meiner Meinung nach ein paar Dinge, die C ++ besser kann als D. Es gibt wahrscheinlich mehr, aber hier sind ein paar, die ich ganz oben auflisten kann:

C ++ hat ein besser durchdachtes Typensystem
Im Moment gibt es einige Probleme mit dem Typensystem in D, die anscheinend zu übersehen sind. Zum Beispiel ist es derzeit nicht möglich, eine const-Struktur in eine Nicht-const-Struktur zu kopieren, wenn die Struktur Klassenobjektreferenzen oder -zeiger enthält, da const transitiv ist und Postblit-Konstruktoren mit Werttypen arbeiten. Andrei sagt, er weiß, wie man das löst, hat aber keine Details angegeben. Das Problem ist sicherlich behebbar (die Einführung von C ++ - Kopierkonstruktoren wäre eine Lösung), aber es ist derzeit ein großes sprachliches Problem.

Ein weiteres Problem, das mich gestört hat, ist das Fehlen von logischen Konstanten (dh nicht mutablewie in C ++). Dies ist großartig, um thread-sicheren Code zu schreiben, macht es jedoch schwierig (unmöglich?), Eine verzögerte Initialisierung innerhalb von const-Objekten durchzuführen (denken Sie an eine const-Funktion 'get', die den zurückgegebenen Wert beim ersten Aufruf erstellt und zwischenspeichert).

Schließlich, da diese bestehenden Probleme, ich mache mir Sorgen darüber , wie der Rest des Typs System ( pure, sharedusw.) mit allem anderen in der Sprache zu interagieren , wenn sie in Gebrauch genommen. Die Standardbibliothek (Phobos) nutzt das fortschrittliche Typensystem von D derzeit nur sehr wenig, daher halte ich es für vernünftig, die Frage zu klären, ob es unter Stress bestehen bleibt. Ich bin skeptisch, aber optimistisch.

Beachten Sie, dass C ++ einige Warzen im Typsystem hat (z. B. nicht-transitives const, erfordert iteratorsowie const_iterator), die es ziemlich hässlich machen, aber während das Typsystem von C ++ in Teilen ein wenig falsch ist, hindert es Sie nicht daran, die Arbeit wie das von D zu erledigen manchmal schon.

Edit: Um das zu verdeutlichen, glaube ich, dass C ++ ein besser durchdachtes Typsystem hat - nicht unbedingt ein besseres - wenn das Sinn macht. Grundsätzlich besteht in DI das Risiko, dass alle Aspekte des Typsystems verwendet werden, die in C ++ nicht vorhanden sind.

D ist manchmal etwas zu bequem
Ein Kritikpunkt, den Sie oft von C ++ hören, ist, dass es einige Probleme auf niedriger Ebene vor Ihnen verbirgt, z. B. einfache Zuweisungen a = b;, die viele Dinge wie das Aufrufen von Konvertierungsoperatoren, das Aufrufen von Überladungszuweisungsoperatoren usw. erledigen können schwer aus dem Code zu sehen. Manche mögen das, manche nicht. So oder so, in D ist es schlechter (besser?) Aufgrund Dinge wie opDispatch, @property, opApply, , lazydie das Potenzial haben , unschuldig aussehenden Code in den Dinge zu ändern , die Sie nicht erwarten.

Ich glaube nicht, dass dies persönlich ein großes Problem ist, aber manche mögen dies als abstoßend empfinden.

D erfordert Garbage Collection
Dies kann als umstritten angesehen werden, da D ohne GC ausgeführt werden kann. Nur weil es möglich ist, heißt das noch lange nicht, dass es praktisch ist. Ohne einen GC verlieren Sie viele Funktionen von D, und die Verwendung der Standardbibliothek ist wie ein Spaziergang durch ein Minenfeld (wer weiß, welche Funktionen Speicher zuweisen?). Persönlich halte ich es für völlig unpraktisch, D ohne GC zu verwenden, und wenn Sie kein GC-Fan sind (wie ich), kann dies ziemlich abstoßend sein.

Naive Array-Definitionen in D
belegen Speicher

int[3] a = [1, 2, 3]; // in D, this allocates then copies
int a[3] = {1, 2, 3}; // in C++, this doesn't allocate

Um die Zuordnung in D zu vermeiden, müssen Sie anscheinend Folgendes tun:

static const int[3] staticA = [1, 2, 3]; // in data segment
int[3] a = staticA; // non-allocating copy

Diese kleinen Zuweisungen hinter deinem Rücken sind gute Beispiele für meine beiden vorherigen Punkte.

Bearbeiten: Beachten Sie, dass dies ein bekanntes Problem ist, an dem gerade gearbeitet wird.
Bearbeiten: Dies ist jetzt behoben. Es findet keine Zuordnung statt.

Fazit
Ich habe mich auf die Negative von D vs C ++ konzentriert, da dies die gestellte Frage ist, aber bitte sehen Sie diesen Beitrag nicht als Aussage, dass C ++ besser ist als D. Ich könnte leicht einen größeren Beitrag von Stellen machen, an denen D besser ist als C ++. Es liegt an Ihnen, die Entscheidung zu treffen, welche Sie verwenden möchten.


Ich habe D vor ein paar Jahren angeschaut (vor 2.0). Garbage Collection war damals nicht wirklich erforderlich - es war standardmäßig vorhanden, aber Sie konnten sich für Low-Level-Code entscheiden. Das, was ich falsch fand, war, dass ich keine Möglichkeit finden konnte, mich wieder anzumelden. In einem baumbasierten Container kann der Bibliothekscode beispielsweise den Speicher für die Baumknoten selbst verwalten. Der gesamte Baum kann weiterhin gesammelt werden, wobei IIRC ein Destruktor ist, der alle diese Knoten sammelt. Objekte, auf die von den Daten in diesem Container verwiesen wird, sollten auch sammelbar sein. Es sollte einen Haken geben, mit dem alle Datenelemente im Baum für den GC markiert werden.
Steve314

3
Sie können den GC immer noch für Low-Level-Code deaktivieren - Peter sagt, dass die Sprache derzeit stark davon abhängt. Sie können den GC auch anweisen, Bereiche außerhalb seines verwalteten Heaps mithilfe der API zu scannen: GC.addRange from core.memory .
Vladimir Panteleev

+1 für den Hinweis, dass die D-Standardbibliothek müllsammelbar ist und dass der GC-off-Code keine nahtlose Interop ist. Ich habe nicht darüber nachgedacht, aber es scheint eine große Hürde zu sein, die es zu überwinden gilt.
Masonk

132

Als ich zu D development kam, war ich in der besonderen Position, einer der Leute zu sein, die am meisten über C ++ wissen. Jetzt bin ich in der noch eigentümlicheren Position, auch einer der Menschen zu sein, die am besten wissen, dass es etwas über D gibt vorteilhafte Position zur Beantwortung dieser Frage. Gleiches gilt für Walter.

Im Großen und Ganzen ist die Frage, was C ++ (und damit meine ich C ++ 2011) besser macht als D, ebenso widersprüchlich wie die Frage: "Wenn Sie einen Fachmann für die Reinigung Ihres Hauses bezahlen, welche Orte werden sie verlassen? dreckiger als vorher? " Was auch immer von Wert war, dass C ++ das tun konnte, was D nicht konnte, es war für mich und Walter immer wie ein wunder Daumen, also gibt es fast per Definition nichts, was C ++ jemals tun kann, was nicht in Ds Reichweite ist.

Eine Sache, die im Sprachdesign selten verstanden wird (weil nur wenige Menschen das Glück haben, tatsächlich etwas zu tun), ist, dass es viel weniger ungezwungene Fehler gibt, als es erscheinen mag. Viele von uns Sprachbenutzern schauen sich das eine oder andere Konstrukt an und sagen: "Ew! Das ist so falsch! Was dachten sie?" Tatsache ist, dass die meisten unangenehmen Fälle in einer Sprache auf einige grundlegende Entscheidungen zurückzuführen sind, die alle stichhaltig und wünschenswert sind, sich jedoch grundlegend widersprechen oder widersprechen (z. B. Modularität und Effizienz, Knappheit und Kontrolle usw.).

Vor diesem Hintergrund werde ich ein paar Dinge aufzählen, die mir einfallen, und für jede erläutere ich, wie Ds Entscheidung aus dem Wunsch resultiert, eine andere Charta auf höherer Ebene zu erfüllen.

  1. D setzt voraus, dass alle Objekte bitweise kopiert werden können. Dies überlässt C ++ eine Minderheit von Designs, insbesondere solchen, die interne Zeiger verwenden, dh eine Klasse, die Zeiger in sich enthält. (Ein solches Design kann ohne oder mit zu vernachlässigenden Kosten für die Effizienz in D übersetzt werden, es wäre jedoch ein Übersetzungsaufwand erforderlich.) Wir haben diese Entscheidung getroffen, um die Sprache erheblich zu vereinfachen, das Kopieren von Objekten effizienter zu gestalten, ohne oder mit minimalem Benutzereingriff, und zu vermeiden Der gesamte Kopierkonstruktions-Morast und die R-Wert-Referenzen sind insgesamt vorhanden.

  2. D verbietet Typen mit mehrdeutigem Geschlecht (die nicht entscheiden können, ob es sich um Werttypen oder Referenztypen handelt). Solche Designs werden in C ++ einhellig gemieden und sind fast immer falsch, aber einige davon sind technisch korrekt. Wir haben diese Wahl getroffen, weil sie meistens falschen Code und nur einen winzigen Bruchteil korrekten Code verbietet, der neu gestaltet werden kann. Wir glauben, dass es ein guter Kompromiss ist.

  3. D erlaubt keine Hierarchien mit mehreren Wurzeln. Ein früheres Poster hier hat sich sehr über dieses spezielle Thema gefreut, aber das ist ausgetreten und es gibt keinen spürbaren Vorteil von Hierarchien ohne Wurzel gegenüber Hierarchien, die alle eine gemeinsame Wurzel haben.

  4. In D kann man zB kein int werfen. Sie müssen ein Objekt werfen, das Throwable erbt. Kein Wettbewerb, bei dem der Stand der Dinge in D besser ist, aber es ist eine Sache, die C ++ kann, die D nicht kann.

  5. In C ++ ist die Kapselungseinheit eine Klasse. In D ist es ein Modul (dh eine Datei). Walter traf diese Entscheidung aus zwei Gründen: Um die Kapselung auf natürliche Weise der Dateisystemschutzsemantik zuzuordnen und die Notwendigkeit eines "Freundes" zu vermeiden. Diese Wahl fügt sich sehr gut in das modulare Gesamtdesign von D ein. Es wäre möglich, Dinge so zu ändern, dass sie eher C ++ ähneln, aber das würde die Dinge zwingen. Die Auswahlmöglichkeiten für den Kapselungsbereich von C ++ sind nur für das physische Design von C ++ von Vorteil.

Es könnte ein oder zwei kleinere Dinge geben, aber insgesamt sollte es so sein.


6
@DeadMG: Damit dies in C ++ funktioniert, benötigt das zu verschiebende Objekt einen Rückverweis auf das Objekt, das darauf verweist (damit es während der Kopierkonstruktion aktualisiert werden kann). In diesem Fall können Sie in D den Postblit-Konstruktor verwenden, um den Zeiger trotzdem zu aktualisieren. Bitte argumentieren Sie nicht gegen D, wenn Sie nur ein vorübergehendes Wissen darüber haben.
Peter Alexander

13
@ Peter: Es sollte eine Referenz sein, auch wenn die Lebensdauer streng auf dem Anwendungsbereich basiert. Ich sollte den Aufwand für die dynamische Zuweisung sowie den Indirektions- und Cache- und Sammlungsaufwand verschwenden, weil ich ihn als Alias ​​verwenden möchte. Ich hoffe auch, dass der Sammler es deterministisch sammeln kann, für eine äquivalente Semantik. Das ist ganz klar nicht unter Kontrolle.
DeadMG

3
@sbi: Die Existenz einer Spitzenklasse hat keinerlei Einfluss auf Ihre Auswahl. Im Klassentypgitter gibt es immer ein Oben und ein Unten. Der Grund ist nur in wenigen Sprachen explizit . Das obere (dh Objekt usw.) ist in mehr Sprachen explizit. Diese Typen existieren immer im Konzept; Wenn sie auch zugänglich sind, bieten sie dem Benutzer der Sprache einfach einige zusätzliche Funktionen, ohne Probleme zu verursachen.
Andrei Alexandrescu

6
@quant_dev: Sie werden froh sein zu hören, dass ein GSoC-Projekt bereits in einem guten Zustand ist, das sich auf lineare Hochleistungsalgebra mit BLAS konzentriert. Es bietet auch "naive" Implementierungen der entsprechenden Grundelemente für Test- und Benchmarking-Zwecke. Um Ihre zweite Frage zu beantworten, setzt Java die Messlatte für den Vergleich numerischer Bibliotheken ziemlich niedrig. Es wird immer die Mühe haben, eine JNI-Barriere für den Zugriff auf hochleistungsfähige Algebra-Bibliotheken zu überwinden, und die Syntax wird schlecht sein, weil Java keine Operatorüberladung aufweist.
Andrei Alexandrescu

4
@ PeterAlexander: DeadMG ist genau das Richtige. "Sie sollten keine Zeiger auf Werttypen verwenden" ist sich der Tatsache bewusst, dass Zeiger in jeder Sprache im Allgemeinen für Werttypen verwendet werden (erwarten Sie wirklich, dass sie Object*so häufig verwendet werden wie ein int*?), Und D scheint dies völlig zu ignorieren die Leistungsstrafe, oder behaupten, dass es nicht existiert. Das ist offensichtlich falsch - der Cache-Fehler ist in vielen Fällen ziemlich auffällig, so dass C ++ immer diesen Flexibilitätsvorteil gegenüber D hat.
Mehrdad

65

Ich denke, es wird Ihnen sehr schwer fallen, in D viel zu finden, was objektiv istschlimmer als C ++. Die meisten Probleme mit D, von denen man objektiv sagen könnte, dass sie schlechter sind, sind entweder Probleme mit der Qualität der Implementierung (die im Allgemeinen darauf zurückzuführen sind, wie jung die Sprache und die Implementierung sind und in letzter Zeit mit rasender Geschwindigkeit behoben wurden) oder sie sind Probleme mit einem Mangel an Bibliotheken von Drittanbietern (die mit der Zeit kommen werden). Die Sprache selbst ist im Allgemeinen besser als C ++, und die Fälle, in denen C ++ als Sprache besser ist, sind im Allgemeinen entweder dort, wo es einen Kompromiss gibt, wo C ++ in eine Richtung und D in eine andere Richtung ging, oder wo jemand subjektive Gründe dafür hat denke, dass einer besser ist als der andere. Die Anzahl der ausgesprochen objektiven Gründe, warum C ++ als Sprache besser ist, dürfte jedoch gering sein.

Tatsächlich muss ich mein Gehirn wirklich aus dem Konzept bringen, warum C ++ als Sprache besser ist als D. Was mir im Allgemeinen einfällt, ist eine Frage der Kompromisse.

  1. Da Ds const transitiv ist und die Sprache unveränderlich ist , hat sie weitaus stärkere Garantien als C ++ const, was bedeutet, dass D keine hat und nicht haben kann mutable. Es kann keine logische const haben . Mit dem const-System von D erhalten Sie also einen enormen Gewinn, aber in manchen Situationen können Sie es einfach nicht so verwenden, constwie Sie es in C ++ getan hätten.

  2. D hat nur einen Umsetzungsoperator, während C ++ 4 hat (5, wenn Sie den C-Umsetzungsoperator zählen). Dies erleichtert im Allgemeinen den Umgang mit Darstellungen in D, ist jedoch problematisch, wenn Sie tatsächlich die zusätzlichen Komplikationen / Vorteile möchten, die diese const_castund ihre Brüder bieten. Aber D ist tatsächlich leistungsfähig genug, dass Sie Templates verwenden können, um C ++ - Casts zu implementieren. Wenn Sie sie also wirklich wollen, können Sie sie haben (und sie können sogar irgendwann in der Standardbibliothek von D landen).

  3. D hat weitaus weniger implizite Casts als C ++ und deklariert mit weitaus höherer Wahrscheinlichkeit, dass zwei Funktionen miteinander in Konflikt stehen (was Sie dazu zwingt, genauer zu bestimmen, welche der Funktionen Sie meinen - entweder mit Casts oder durch Angabe des vollständigen Modulpfads ). Manchmal kann das ärgerlich sein, aber es verhindert alle Arten von Problemen bei der Funktionsentführung . Sie wissen, dass Sie wirklich die Funktion aufrufen, die Sie wollen.

  4. Ds Modulsystem ist weitaus sauberer als das #includes von C ++ (ganz zu schweigen davon, dass es beim Kompilieren viel schneller ist), aber es fehlen jegliche Namensräume, die über die Module selbst hinausgehen. Wenn Sie also einen Namespace innerhalb eines Moduls benötigen, müssen Sie die Java-Route einschlagen und statische Funktionen für eine Klasse oder Struktur verwenden. Es funktioniert, aber wenn Sie wirklich Namespaces benötigen, ist es offensichtlich nicht so sauber wie echte Namespaces. In den meisten Situationen ist der Namespace, den die Module selbst zur Verfügung stellen, jedoch ausreichend (und ziemlich ausgefeilt, wenn es um Dinge wie Konflikte geht).

  5. Wie Java und C # hat D eine einfache Vererbung und keine mehrfache Vererbung. Im Gegensatz zu Java und C # bietet es jedoch einige fantastische Möglichkeiten, den gleichen Effekt zu erzielen, ohne dass alle Probleme auftreten, die die mehrfache Vererbung von C ++ mit sich bringt (und die mehrfache Vererbung von C ++ kann sehr chaotisch werden) manchmal). D hat nicht nur Schnittstellen , sondern auch String-Mixins , Template-Mixins und diesen Alias . Das Endergebnis ist also wahrscheinlich leistungsfähiger und weist nicht alle Probleme auf, die die Mehrfachvererbung von C ++ verursacht.

  6. Ähnlich wie in C # trennt D Strukturen und Klassen . Klassen sind Referenztypen Object, die vererbt und abgeleitet sind , während Strukturen Werttypen ohne Vererbung sind. Diese Trennung kann sowohl gut als auch schlecht sein. Es beseitigt das klassische Slicing-Problem in C ++ und hilft dabei, Typen, die wirklich Werttypen sind, von solchen zu trennen, die polymorph sein sollen, aber zumindest könnte die Unterscheidung für einen C ++ - Programmierer zunächst ärgerlich sein. Letztendlich hat es eine Reihe von Vorteilen, aber es zwingt Sie dazu, etwas anders mit Ihren Typen umzugehen.

  7. Member - Funktionen von Klassen sind polymorph standardmäßig. Sie können sie nicht als nicht virtuell deklarieren . Es ist Sache des Compilers, zu entscheiden, ob dies möglich ist (was wirklich nur der Fall ist, wenn sie final sind und eine Funktion einer Basisklasse nicht überschreiben). Das könnte also in einigen Fällen ein Leistungsproblem sein. Wenn Sie den Polymorphismus jedoch wirklich nicht benötigen, müssen Sie nur Strukturen verwenden , und das ist kein Problem.

  8. D hat eine eingebaute Müllabfuhr . Viele von C ++ würden dies als ernstzunehmenden Nachteil betrachten, und um ehrlich zu sein, könnte die Implementierung derzeit einige ernstzunehmende Arbeiten erfordern. Es hat sich verbessert, aber es ist definitiv noch nicht auf dem Niveau von Javas Müllsammler. Dies wird jedoch durch zwei Faktoren gemildert. Erstens , wenn Sie hauptsächlich Strukturen und andere Datentypen auf dem Stack verwenden, ist dies kein großes Problem. Wenn Ihr Programm nicht ständig Dinge auf dem Heap zuordnet und freigibt, ist dies in Ordnung. Und zweitens können Sie den Garbage Collector überspringen , wenn Sie möchten, und einfach Cs mallocund verwenden free. Es gibt einige Sprachfunktionen (z. B. Array-Slicing)), die Sie vermeiden oder mit denen Sie vorsichtig sein müssen, und einige der Standardbibliotheken sind ohne die Verwendung des GC (insbesondere der Zeichenfolgenverarbeitung) nicht wirklich verwendbar , aber Sie können in D schreiben, ohne den Garbage Collector zu verwenden, wenn du willst es wirklich. Das Schlaue ist wahrscheinlich, es im Allgemeinen zu verwenden und dann zu vermeiden, wenn die Profilerstellung zeigt, dass es Probleme für leistungskritischen Code verursacht. Sie können es jedoch vollständig vermeiden, wenn Sie möchten. Und die Qualität der GC -Implementierung wird sich mit der Zeit verbessern, wodurch viele der Bedenken beseitigt werden, die die Verwendung eines GC verursachen kann. Letztendlich ist der GC also kein so großes Problem, und im Gegensatz zu Java können Sie ihn vermeiden, wenn Sie möchten.

Es gibt wahrscheinlich auch andere, aber genau das kann ich mir gerade einfallen lassen. Und wenn Sie bemerken, sind sie alle Kompromisse. D entschied sich dafür, einige Dinge anders zu machen als C ++, die eindeutige Vorteile gegenüber C ++ haben, aber auch einige Nachteile. Was besser ist, hängt davon ab, was Sie tun. In vielen Fällen wird es wahrscheinlich erst schlimmer erscheinen, und wenn Sie sich daran gewöhnt haben, werden Sie kein Problem damit haben. Wenn überhaupt, werden die Probleme in D im Allgemeinen neue sein, die durch neue Dinge verursacht werden, die andere Sprachen vorher nicht oder nicht ganz so gemacht haben wie D. Insgesamt hat D sehr gut aus den Fehlern von C ++ gelernt.

Und D als Sprache verbessert C ++ in so vielen Punkten, dass ich denke, dass es im Allgemeinen der Fall ist, dass D objektiv besser ist.

  1. D hat bedingte Kompilierung . Dies ist eine der Funktionen, die ich beim Programmieren in C ++ häufig vermisse. Wenn C ++ es hinzufügen würde, würde sich C ++ sprunghaft verbessern, wenn es um Dinge wie Vorlagen geht.

  2. D hat eine Kompilierzeitreflexion .

  3. Variablen sind standardmäßig thread-lokal, können es aber auch sein, sharedwenn Sie dies möchten. Dies macht den Umgang mit Threads weitaus sauberer als in C ++. Sie haben die volle Kontrolle. Sie verwenden können , immutableund Message - Passing zwischen Threads zu kommunizieren, oder Sie können Variablen machen sharedund tun es die C ++ Art und Weise mit Mutexe und Bedingungsvariablen. Selbst das wird gegenüber C ++ durch die Einführung von Synchronized (ähnlich wie C # und Java) verbessert . Die Threading-Situation von D ist also weitaus besser als die von C ++.

  4. Die Vorlagen von D sind weitaus leistungsfähiger als die von C ++, sodass Sie weitaus mehr und einfacher tun können. Und mit der Zugabe von Template - Einschränkungen sind die Fehlermeldungen Art und Weise besser , als sie in C ++. D macht Vorlagen sehr leistungsfähig und benutzerfreundlich. Es ist kein Zufall, dass der Autor von Modern C ++ Design einer der Hauptmitarbeiter von D ist. Ich finde, dass C ++ - Vorlagen im Vergleich zu D-Vorlagen ernsthaft fehlen, und es kann manchmal sehr frustrierend sein, wenn in C ++ programmiert wird.

  5. D verfügt über eine integrierte Vertragsprogrammierung .

  6. D verfügt über ein integriertes Unit-Test- Framework.

  7. D unterstützt Unicode mit string(UTF-8), wstring(UTF-16) und dstring(UTF-32). Es macht es einfach, mit Unicode umzugehen. Und wenn Sie nur stringUnicode verwenden möchten und sich im Allgemeinen nicht um Unicode kümmern möchten , können Sie dies. Ein gewisses Verständnis der Grundlagen von Unicode hilft jedoch bei einigen der Standardfunktionen der Bibliothek.

  8. Das Überladen von Operatoren in D ist viel angenehmer als in C ++, sodass Sie mit einer Funktion mehrere Operatoren gleichzeitig überladen können. Ein hervorragendes Beispiel hierfür ist, wenn Sie die grundlegenden arithmetischen Operatoren überladen müssen und ihre Implementierungen bis auf den Operator identisch sind. String-Mixins machen es zu einem Kinderspiel und ermöglichen Ihnen eine einfache Funktionsdefinition für alle.

  9. Die Arrays von D sind weitaus besser als die von C ++. Sie sind nicht nur ein richtiger Typ mit einer Länge, sondern können auch angehängt und in der Größe geändert werden. Sie zu verketten ist einfach. Und das Beste ist, dass sie in Scheiben schneiden . Und das ist ein großer Segen für eine effiziente Array-Verarbeitung. Strings sind Arrays von Zeichen in D, und es ist kein Problem (in der Tat ist es großartig!), Weil Ds Arrays so mächtig sind.

Ich könnte weiter und weiter gehen. Viele der Verbesserungen, die D bietet, sind Kleinigkeiten (wie die Verwendung thisfür Konstruktornamen oder das Nichtzulassen von Anweisungen oder Schleifenkörpern, bei denen ein Semikolon der gesamte Körper ist), aber einige von ihnen sind ziemlich groß, und wenn Sie alles zusammenfassen, ist es sorgt für ein viel besseres Programmiererlebnis. C ++ 0x fügt einige der Funktionen hinzu, die D besitzt und denen C ++ fehlte (z. B. autound Lambdas), aber trotz all seiner Verbesserungen wird es immer noch nicht viel geben, was objektiv besser an C ++ als Sprache ist als D.

Es steht außer Frage, dass es viele subjektive Gründe gibt, sich untereinander zu mögen, und die relative Unreife der Implementierung von D kann zuweilen ein Problem sein (obwohl sie sich in letzter Zeit sehr schnell verbessert hat - insbesondere seit die Repositorys auf Github verschoben wurden ). und das Fehlen von Bibliotheken von Drittanbietern kann definitiv ein Problem sein (obwohl die Tatsache, dass D leicht C-Funktionen aufrufen kann - und in geringerem Maße C ++ - Funktionen - definitiv das Problem mindert). Dies sind jedoch eher Probleme mit der Qualität der Implementierung als mit der Sprache selbst. Und da die Qualität der Implementierungsprobleme behoben ist, wird die Verwendung von D umso angenehmer.

Ich nehme also an, dass die kurze Antwort auf diese Frage "sehr wenig" ist. D ist als Sprache im Allgemeinen C ++ überlegen.


2
Garbage Collection-Sprachen belegen 2-5x mehr Speicher als Nicht-GC langs (laut Alexandrescus Vortrag über YT), so dass dies definitiv ein Problem darstellt, wenn dies (Mem-Nutzung) der Engpass ist.
NoSenseEtAl

9

RAII- und Stapelspeicherauslastung

D 2.0 lässt RAII nicht auf dem Stapel zu, da der Wert des scopeSchlüsselworts beim Zuweisen von Klasseninstanzen auf dem Stapel entfernt wurde.

Sie können in D keine Vererbung vom Typ Wert durchführen, sodass Sie gezwungen sind, eine Heap-Zuordnung für jede Form von RAII vorzunehmen.
Das heißt, es sei denn, Sie verwenden emplace, aber die Verwendung ist sehr schmerzhaft, da Sie den Speicher manuell zuweisen müssen. (Ich habe es noch nicht für praktisch befunden, es emplacein D zu verwenden .)


6

C ++ zwingt Sie viel besser dazu, wortreich zu sein. Dies kann in Ihren Augen besser oder schlechter sein, je nachdem, ob Sie Inferenz oder Ausführlichkeit mögen.

Vergleichen Sie die Laufzeiterfassung in C ++ :

template <typename ReturnType, typename... Args>
function<ReturnType (Args...)> memoize(function<ReturnType (Args...)> func)
{
    map<tuple<Args...>, ReturnType> cache;
    return ([=](Args... args) mutable {
            tuple<Args...> t(args...);
            return cache.find(t) == cache.end()
                ? cache[t] : cache[t] = func(args...);
    });
}

mit der gleichen Sache in D:

auto memoize(F)(F func)
{
    alias ParameterTypeTuple!F Args;
    ReturnType!F[Tuple!Args] cache;
    return (Args args)
    {
        auto key = tuple(args);
        return key in cache ? cache[key] : (cache[key] = func(args));
    };
}

Beachten Sie beispielsweise die zusätzliche Ausführlichkeit von template <typename ReturnType, typename... Args>versus (F), Args...versus Args, args...versus argsusw.
C ++ ist besser oder schlechter gesagt ausführlicher.

Natürlich können Sie dies auch in D tun:

template memoize(Return, Args...)
{
    Return delegate(Args) memoize(Return delegate(Args) func)
    {
        Return[Tuple!Args] cache;
        return delegate(Args args)
        {
            auto key = tuple(args);
            return key in cache ? cache[key] : (cache[key] = func(args));
        };
    }
}

und sie würden fast identisch aussehen, aber dann würde dies ein erfordern delegate, während das Original jedes aufrufbare Objekt akzeptierte . (Die C ++ 0x-Version erfordert einstd::function Objekt, so oder so, es ist ausführlicher und restriktiver in seinen Eingaben ... was gut sein könnte, wenn Sie Ausführlichkeit mögen, schlecht, wenn Sie dies nicht tun.)


2

Ich weiß nicht viel über D, aber viele, viele C ++ - Programmierer, von denen ich weiß, dass sie es nicht mögen, und ich persönlich muss zustimmen, dass ich das Aussehen von D nicht mag und nicht näher darauf eingehen werde.

Um zu verstehen, warum D nicht mehr an Bodenhaftung gewinnt, müssen Sie zunächst verstehen, was Menschen an C ++ interessiert. Mit einem Wort, der Hauptgrund ist die Kontrolle. Wenn Sie in C ++ programmieren, haben Sie die vollständige Kontrolle über Ihr Programm. Möchten Sie die Standardbibliothek ersetzen? Du kannst. Möchten Sie unsichere Zeigermodelle erstellen? Du kannst. Willst du die Beständigkeit verletzen? Du kannst. Möchten Sie die Speicherzuordnung ersetzen? Du kannst. Möchten Sie rohen Speicher ohne Rücksicht auf seinen Typ kopieren? Wenn du wirklich willst. Möchten Sie von mehreren Implementierungen erben? Es ist deine Beerdigung. Zum Teufel, Sie können sogar Müllbibliotheken kaufen, so wie der Böhm-Sammler. Dann haben Sie Probleme wie die Leistung, die eng mit der Kontrolle zusammenhängt - je mehr Kontrolle ein Programmierer hat, desto optimierter kann er sein Programm erstellen.

Hier sind ein paar Dinge, die ich gesehen habe, als ich ein wenig recherchiert und mit ein paar Leuten gesprochen habe, die es versucht haben:

Einheitliche Typhierarchie. C ++ - Benutzer verwenden Vererbung sehr selten, die meisten C ++ - Programmierer bevorzugen die Komposition, und Typen sollten nur durch Vererbung verknüpft werden, wenn es einen sehr guten Grund dafür gibt. Das Konzept des Objekts verletzt dieses Prinzip stark, indem es jeden Typ verknüpft. Darüber hinaus verstößt es gegen eines der grundlegendsten Prinzipien von C ++ - Sie verwenden nur das, was Sie wollen. Das Fehlen einer Wahlmöglichkeit für das Erben von Object und die damit verbundenen Kosten stehen sehr stark im Widerspruch zu dem, wofür C ++ als Sprache steht, um dem Programmierer die Kontrolle über sein Programm zu geben.

Ich habe von Problemen mit Funktionen und Delegierten gehört. Anscheinend hat D sowohl Funktionen als auch Delegierte als zur Laufzeit aufrufbare Funktionstypen und sie sind nicht gleich, aber austauschbar oder ... etwas? Mein Freund hatte einige Probleme mit ihnen. Dies ist definitiv eine Herabstufung von C ++, die nur hat std::functionund Sie sind fertig.

Dann hast du Kompatibilität. D ist nicht besonders kompatibel mit C ++. Ich meine, keine Sprache ist mit C ++ kompatibel, seien wir ehrlich, mit Ausnahme von C ++ / CLI, das eine Art Betrug darstellt, aber als Eintrittsbarriere muss es erwähnt werden.

Dann gibt es noch ein paar andere Dinge. Lesen Sie zum Beispiel einfach den Wikipedia-Eintrag.

import std.metastrings;
pragma(msg, Format!("7! = %s", fact_7));
pragma(msg, Format!("9! = %s", fact_9));

printfist eine der unsichersten Funktionen, die jemals entwickelt wurden, in derselben Familie wie große Probleme wie getsin der alten C-Standard-Bibliothek. Wenn Sie im Stapelüberlauf danach suchen, werden Sie viele, viele Fragen im Zusammenhang mit dem Missbrauch finden. Grundsätzlich printfist eine Verletzung von DRY- Sie geben den Typ in der Formatzeichenfolge an und geben ihn dann erneut an, wenn Sie ihm ein Argument geben. Eine Verletzung von DRY, bei der, wenn Sie etwas falsch machen, sehr schlimme Dinge passieren, wenn Sie eine Typendefinition von einer 16-Bit-Ganzzahl in eine 32-Bit-Ganzzahl ändern. Es ist auch überhaupt nicht erweiterbar - stellen Sie sich vor, was passieren würde, wenn jeder seine eigenen Formatspezifizierer erfinden würde. Die iostreams von C ++ sind möglicherweise langsam und die Auswahl des Operators ist möglicherweise nicht die beste. Die Benutzeroberfläche kann Arbeit gebrauchen. Grundsätzlich ist jedoch die Sicherheit der Iostreams gewährleistet und DRY wird nicht verletzt. Sie können problemlos erweitert werden. Das kann man nicht sagen printf.

Keine Mehrfachvererbung. Das ist ganz und gar nicht der C ++ Weg. C ++ - Programmierer erwarten, dass sie die vollständige Kontrolle über ihr Programm haben, und die Sprache, die das erzwingt, wovon Sie nicht erben können, verstößt gegen dieses Prinzip. Darüber hinaus wird die Vererbung (noch) anfälliger, da der gesamte Code Ihres Benutzers plötzlich beschädigt wird, wenn Sie einen Typ von einer Schnittstelle in eine Klasse ändern, weil Sie eine Standardimplementierung oder ähnliches bereitstellen möchten. Das ist keine gute Sache.

Ein anderes Beispiel ist stringund wstring. In C ++ ist es bereits sehr schmerzhaft, zwischen ihnen konvertieren zu müssen. Unterstützt diese Bibliothek Unicode, und diese alte C-Bibliothek verwendet nur const char*unterschiedliche Versionen derselben Funktion, abhängig vom gewünschten String-Argumenttyp. Insbesondere die Windows-Header enthalten zum Beispiel einige äußerst irritierende Makros, um das Problem zu lösen, das häufig Ihren eigenen Code stören kann. Das Hinzufügen dstringzu der Mischung wird die Sache nur verschlimmern, da Sie jetzt anstelle von zwei Zeichenfolgentypen drei verwalten müssen. Wenn Sie mehr als einen Zeichenfolgentyp haben, werden die Wartungsprobleme zunehmen und sich wiederholender Code für Zeichenfolgen eingeführt.

Scott Meyers schreibt:

D ist eine Programmiersprache, die Programmierern dabei hilft, die Herausforderungen der modernen Softwareentwicklung zu meistern. Dies geschieht durch die Förderung von Modulen, die über präzise Schnittstellen miteinander verbunden sind, einem Zusammenschluss eng integrierter Programmierparadigmen, sprachgesteuerter Thread-Isolierung, modularer Sicherheit, eines effizienten Speichermodells und mehr.

Eine sprachgesteuerte Thread-Isolierung ist kein Plus. C ++ - Programmierer erwarten volle Kontrolle über ihre Programme, und die Sprache, die etwas erzwingt, entspricht definitiv nicht den Anweisungen des Arztes.

Ich werde auch die String-Manipulation während der Kompilierung erwähnen. D kann D-Code während der Kompilierung interpretieren. Dies ist kein Plus. Betrachten Sie die massiven Kopfschmerzen, die durch den relativ eingeschränkten Präprozessor von C verursacht werden, der allen erfahrenen C ++ - Programmierern bekannt ist, und stellen Sie sich dann vor, wie sehr diese Funktion missbraucht wird. Die Möglichkeit, D-Code zur Kompilierungszeit zu erstellen, ist großartig, sollte jedoch semantisch und nicht syntaktisch sein.

Außerdem ist ein gewisser Reflex zu erwarten. D hat eine Garbage Collection, die C ++ - Programmierer mit Sprachen wie Java und C # assoziieren werden, die in Philosophien ziemlich direkt dagegen stehen, und die syntaktischen Ähnlichkeiten werden sie auch in Erinnerung rufen. Dies ist nicht unbedingt objektiv zu rechtfertigen, aber es ist etwas, das auf jeden Fall beachtet werden sollte.

Grundsätzlich bietet es nicht so viel, wie C ++ - Programmierer es nicht können. Vielleicht ist es einfacher, ein faktorielles Metaprogramm in D zu schreiben, aber wir können bereits faktorielle Metaprogramme in C ++ schreiben. Vielleicht in D Sie können einen Compiler-ray-Tracer schreiben, aber niemand will wirklich , dass auf jeden Fall tun. Im Vergleich zu den grundlegenden Verstößen gegen die C ++ - Philosophie ist das, was Sie in D tun können, nicht besonders bemerkenswert.

Auch wenn diese Dinge nur Probleme auf der Oberfläche sind, bin ich mir ziemlich sicher, dass die Tatsache, dass D auf der Oberfläche überhaupt nicht wie C ++ aussieht, wahrscheinlich ein guter Grund dafür ist, dass viele C ++ - Programmierer nicht nach D migrieren. Möglicherweise muss D eine bessere Jobwerbung selbst erledigen.


9
@DeadMG: Es ist zu 100% falsch und es fehlt der Sinn zu sagen. Dies ist definitiv ein Downgrade von C ++, was einfach so ist std::functionund du bist fertig. Warum? Weil Sie zum Beispiel auch Funktionszeiger haben. Es ist genau dasselbe in D: Ds "Funktionen" sind Funktionszeiger, und Ds "Delegaten" sind die gleichen wie C ++ std::function(mit der Ausnahme, dass sie eingebaut sind). Es gibt nirgendwo ein "Downgrade" - und es gibt eine 1: 1-Entsprechung zwischen ihnen, daher sollte es nicht verwirrend sein, wenn Sie mit C ++ vertraut sind.
Mehrdad

10
@ Mark Trapp: Ich muss zugeben, dass ich Ihre Haltung zum Thema nicht ganz verstehe - Kommentare sind nicht dazu gedacht, eine Antwort zu kommentieren , wissen Sie ?
klickverbot

6
@ Mark Trapp: Mein Punkt ist, dass die meisten Kommentare hier nicht überholt waren (die Metadiskussion, die Sie verlinkt haben, gilt speziell für Vorschläge, die bereits in den ursprünglichen Beitrag aufgenommen wurden), sondern auf tatsächliche Ungenauigkeiten im Beitrag hingewiesen haben, die noch vorhanden sind .
klickverbot

7
Anmerkung zum Format: Die Formatfunktion von D ist typsicher (behebt die Sicherheits- / Überlaufprobleme) und verletzt DRY nicht, da die Formatzeichenfolge nur angibt, wie die Argumente formatiert werden sollen, nicht ihre Typen. Dies ist dank der typsicheren Variadics von D möglich. Daher ist dieser Einwand zumindest völlig ungültig.
Justin W

17
@Mark: Was auch immer die aktuelle Politik in Bezug auf sie ist, ich finde es dumm und hinderlich, dass Kommentardiskussionen gelöscht werden . Ich denke, diese Antwort hatte umfangreiche Diskussionen (die mich jetzt interessieren), aber ich bin nicht sicher, und ich habe keine Möglichkeit, herauszufinden. Der Raum, mit dem Sie verbunden sind, hat weit über 10.000 Nachrichten, und ich habe überhaupt keine Chance, eine Diskussion zu finden, an die ich mich anscheinend erinnern kann, aber an deren Inhalt ich mich nicht erinnern kann. Diskussionen über diese Antwort gehören hierher, zu dieser Antwort und nicht zu einem Chatroom, in dem sie in Diskussionen über Sex, Drogen und Rock'n'Roll verwickelt sein könnten.
sbi

1

Eine Sache, die ich in C ++ schätze, ist die Fähigkeit, ein Funktionsargument oder einen Rückgabewert als C ++ - Referenz anstelle eines Zeigers zu dokumentieren, was impliziert, dass ein Nichtwert verwendet nullwird.

D-Version:

class A { int i; }

int foo(A a) {
    return a.i; // Will crash if a is null
}

int main() {
    A bar = null;
    // Do something, forgetting to set bar in all
    // branches until finally ending up at:
    return foo(bar);
}

C ++ Version:

class A { int i; };

int foo(A& a) {
    return a.i; // Will probably not crash since
                // C++ references are less likely
                // to be null.
}

int main() {
    A* bar = null;
    // Do something, forgetting to set bar in all
    // branches until finally ending up at:
    // Hm.. I have to dereference the bar-pointer
    // here, otherwise it wont compile.  Lets add
    // a check for null before.
    if (bar)
        return foo(*bar);
    return 0;
}

Um fair zu sein, können Sie C ++ sehr nahe kommen, indem Sie Aein D erstellen structund das foo()-argument als a markieren ref(Klassen sind Referenztypen und Strukturen sind Werttypen in D, ähnlich wie in C #).

Ich glaube, es gibt einen Plan, NonNullablestattdessen eine Vorlage für Klassen als D-Standard-Bibliothekskonstrukt zu erstellen . Trotzdem mag ich die Kürze von nur im Type&Vergleich zu NonNullable(Type)und würde es vorziehen, als Standard nicht nullbar zu sein (Rendern von so etwas wie Typeund Nullable(Type)). Aber es ist zu spät, um das für D zu ändern, und ich komme jetzt vom Thema ab.


3
Sowohl Funktionsargumente als auch Rückgabewerte in D können mit markiert werden ref, um den gleichen Effekt wie in C ++ zu erzielen &. Der einzige große Unterschied besteht darin, dass Sie refkeine Zeit benötigen, auch wenn dies der Fall ist const.
Jonathan M Davis

Mir gefällt die Art und Weise, wie die Rückgabe von Verweisen auf lokale Variablen in D verboten ist. Das war mir erst bewusst, als ich Ihren Kommentar gelesen habe. Sie können jedoch immer noch eine nicht lokale Nullreferenz zurückgeben, ohne darüber nachdenken zu müssen, wie es der C-Dereferenzierungsoperator veranlasst.
Lumor

Sie verwirren die Dinge. Klassen sind immer Referenzen, und das ist getrennt von ref. Referenzen in D sind wie Referenzen in Java. Sie sind verwaltete Zeiger. Übergeben oder Zurückgeben mit ref ist wie Übergeben oder Zurückgeben mit & in C ++. Das Übergeben einer Klassenreferenz per ref entspricht dem Übergeben eines Zeigers in C ++ mit & (z. B. A * &). Klassen gehen nicht auf den Stapel. Ja, NonNullable würde es ermöglichen, eine Klassenreferenz zu haben, die garantiert nicht null ist, aber das ist völlig unabhängig von ref. Was Sie im C ++ - Code versuchen, funktioniert in D nicht, weil Klassen nicht auf dem Stapel abgelegt werden. Strukturen tun.
Jonathan M Davis

1
Ja, es wäre schön, eine Klassenreferenz zu haben, die nicht null ist, aber C ++ schafft es, das zu tun, was Sie anzeigen, da Klassen auf dem Stapel gespeichert und Zeiger dereferenziert werden können. Und während Sie Zeiger in D dereferenzieren können , sind Klassen Referenzen und keine Zeiger, sodass Sie sie nicht dereferenzieren können. Da Sie sie nicht auf den Stapel legen und nicht dereferenzieren können, gibt es in D keine Möglichkeit, eine Klasse zu haben, die nicht null sein kann. Es ist ein Verlust, aber NonNullable wird ihn beheben, und die Gewinne aus der Trennung von Strukturen und Klassen sind im Allgemeinen ohnehin größer.
Jonathan M Davis

2
C ++ - Referenzen können laut Sprachstandard nicht null sein (die Aussage "wahrscheinlich wird nicht null sein" ist falsch, da sie nicht null sein kann). Ich wünschte, es gäbe eine Möglichkeit, null als gültigen Wert für eine Klasse zu verbieten.
Sternberg

1

Das Wichtigste, was C ++ "besser macht" als D, ist die Anbindung an Legacy-Bibliotheken . Verschiedene 3D-Engines, OpenCL und Ähnliches. Da D neu ist, stehen wesentlich weniger verschiedene Bibliotheken zur Auswahl.

Ein weiterer wichtiger Unterschied zwischen dem C ++ und dem D ist, dass der C ++ mehrere finanziell unabhängige Anbieter hat, aber seit 2014 hat der D praktisch nur noch einen , das 2-Mann-Team, das ihn geschaffen hat. Es ist interessant, dass das "Prinzip der zweiten Quelle" , wonach Projekte niemals von Technologie abhängen sollten, Komponenten, die nur einen einzigen Anbieter haben, auch für Software zu gelten scheint.

Zum Vergleich: Die erste Version des Ruby-Interpreters wurde vom Erfinder von Ruby, dem Yukihiro Matsumoto, geschrieben, aber der Mainstream-Ruby-Interpreter der Ära 2014 wurde von anderen praktisch von Grund auf neu geschrieben. Daher kann Ruby als eine Sprache angesehen werden, die mehr als einen finanziell unabhängigen Anbieter hat. D hingegen kann eine großartige Technologie sein, hängt jedoch von den wenigen Entwicklern ab, die sie entwickeln.

Die Geschichte von Java zeigt, dass selbst wenn eine Technologie, in diesem Fall Java, einen guten, aber einzigen Finanzier hat, das Risiko groß ist, dass die Technologie unabhängig von der großen Anzahl von Unternehmensbenutzern im Wesentlichen verloren geht. Ein Zitat der Apache Software Foundation , in der die EG für "Executive Committee" steht:

Oracle hat der EC eine Java SE 7-Spezifikationsanforderung und -Lizenz zur Verfügung gestellt, die sich selbst widersprechen, den Vertrieb unabhängiger Implementierungen der Spezifikation stark einschränken und vor allem den Vertrieb unabhängiger Open Source-Implementierungen der Spezifikation untersagen.

Als historische Anmerkung kann gesagt werden, dass Java-Applets jahrelang vor der Entwicklung von HTML5-WebGL eine hardwarebeschleunigte 3D-Leinwand hatten. Das Problem mit der Startgeschwindigkeit von Java-Applets hätte gelöst werden können, wenn Java ein Community-Projekt gewesen wäre, aber die Führungskräfte des einzigen Finanziers von Java, Sun Microsystems, fanden es nicht wichtig genug, die Java-Implementierung zu reparieren. Das Endergebnis: HTML5-Canvas von mehreren Anbietern als Replikat der Java-GUI-Frameworks (Swing usw.). Interessanterweise hat die Programmiersprache Python auf der Serverseite die gleichen Vorteile, die Java versprochen hat: einmal schreiben, auf jedem Server ausführen, unabhängig von der Hardware, vorausgesetzt, die Python-Anwendung ist nicht zu Maschinencode kompiliert. Der Python ist ungefähr so ​​alt / jung wie der Java, aber im Gegensatz zum Java

Zusammenfassung:

Bei der Bewertung von Technologien für den produktiven Einsatz sind die wichtigsten Eigenschaften von Technologien die Menschen, die sie entwickeln, der soziale Prozess, in dem die Entwicklung stattfindet, und die Anzahl der finanziell unabhängigen Entwicklungsteams.

Ob es vorteilhafter ist, Technologie T1 gegenüber Technologie T2 zu verwenden, hängt von den Anbietern der Technologien ab und ob Technologie T1 es ermöglicht, projektbezogene Probleme billiger zu lösen als T2. Wenn beispielsweise das Problem eines einzelnen Anbieters ignoriert würde, wäre Java für Informationssysteme eine "bessere" Technologie als C ++, da Java-Binärdateien beim Deployment auf neue Hardware und bei der Entwicklung von Software zur Speicherverwaltung nicht neu kompiliert werden müssen ist für Java kleiner als für C ++. Projekte, die von Grund auf neu entwickelt wurden, z. B. Projekte, die nicht von anderen Bibliotheken abhängen, sind möglicherweise in D günstiger zu entwickeln als in C ++. Andererseits hat C ++ mehrere Anbieter und ist daher auf lange Sicht weniger riskant . (Das Java-Beispiel, in dem Sun Microsystems fast in Ordnung war,

Eine mögliche Problemumgehung für einige der C ++ - Einschränkungen

Eine der möglichen Problemumgehungen für einige der Einschränkungen von C ++ ist die Verwendung eines Entwurfsmusters, bei dem die anfängliche Aufgabe in Teile zerlegt und die Teile "sortiert" werden (klassifiziert, gruppiert, geteilt, andere-nette-Wörter-für- das Gleiche) zu 2 Klassen: Steuerlogik bezogene Aufgaben , bei denen Speicherzugriffsmuster keine Lokalität zulassen; Signalverarbeitungsähnliche Aufgaben , bei denen die Lokalität leicht zu erreichen ist. Die signalverarbeitenden "Like" -Aufgaben können als eine Reihe relativ vereinfachter Konsolenprogramme implementiert werden. Die Aufgaben im Zusammenhang mit der Steuerlogik werden alle in einem einzelnen Skript ausgeführt, das in Ruby oder Python oder in einer anderen Form geschrieben ist, bei der der Komfort der Softwareentwicklung Vorrang vor der Geschwindigkeit hat.

Um eine kostspielige Initialisierung von Betriebssystemprozessen und das Kopieren von Daten zwischen Betriebssystemprozessen zu vermeiden, kann der Satz kleiner C ++ - Konsolenanwendungen als einzelnes C ++ - Programm implementiert werden, das vom Ruby / Python / etc als "Servlet" gebootet wird. Skript. Der Ruby / Python / etc. Skript fährt das Servlet vor dem Beenden herunter. Kommunikation zwischen dem "Servlet" und dem Ruby / Python / etc. Das Skript findet über eine Linux Named Pipe oder einen ähnlichen Mechanismus statt.

Wenn sich die anfängliche Aufgabe nicht leicht in Teile aufteilen lässt, die in die beiden oben genannten Klassen eingeteilt werden können, besteht ein Versuch darin, das Problem neu zu formulieren, sodass sich die anfängliche Aufgabe ändert.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.