Von C zu Rust wechseln?



  • hustbaer schrieb:

    Rc<T> bzw. Arc<T> war das was ich wissen wollte.
    Also auf Library-Ebene behandelt. Schade.

    Nee... Gut so! Es hat in Rust so angefangen, wie Du es für besser hältst. Aber man will eben auch für eine „Systemprogrammiersprache“ eine minimale Runtime haben. Und der Sprachkern war dann irgendwann mächtig genug, dass man es in Form einer Bibliothek anbieten konnte.

    hustbaer schrieb:

    Ich glaube nämlich dass es gescheiter wäre das der VM/Runtime aufs Auge zu drücken, da man dann mehr Möglichkeiten zur Optimierung hat.

    Und ich glaube, dass das überhaupt gar keine Rolle spielt. Shared ownership benutze ich selten bis gar nicht. Wo siehst Du denn da Optimierungspotential?



  • Interessanter Vortrag über Servo.
    Leider haben die zu weniger Entwicklerresourcen. Vielleicht will einer von euch mithelfen kleinere Aufgaben zu implementieren? Einigen von euch traue ich das zu!

    https://www.youtube.com/watch?v=7q9vIMXSTzc

    Viele der noch umzusetzenden Elemente sind aber eher einfache Kopien aus den jeweiligen Spezifikationen, weshalb auch viele Studenten Code als Kursaufgaben beitragen, wie Matthews erklärt.

    http://www.golem.de/news/mozilla-servo-der-wikipedia-browser-1502-112145.html



  • krümelkacker schrieb:

    hustbaer schrieb:

    Ich glaube nämlich dass es gescheiter wäre das der VM/Runtime aufs Auge zu drücken, da man dann mehr Möglichkeiten zur Optimierung hat.

    Und ich glaube, dass das überhaupt gar keine Rolle spielt. Shared ownership benutze ich selten bis gar nicht. Wo siehst Du denn da Optimierungspotential?

    Mir geht es um "immutable" Zeugs.
    Das kann man entweder kopieren, oder man braucht Shared-Ownership. Anwendungsbeispiele gibt's genügend.

    z.B. wenn man riesen XML Files laden möchte, ist es nett, wenn man die Namen von Tags nicht zigtausendfach kopiert abspeichern muss. Und hier wäre auch wichtig dass keine Performance verschenkt wird.

    Bzw. überall wo "ausborgen" nicht reicht, aber nicht kopiert werden müsste, weil halt nix geändert werden muss. z.B. wenn ich nen String (oder sonst ein Objekt) aus meiner Settings-Klasse nehme und es als Parameter für ne asynchrone Operation (HTTP Request, ...) verwende. Zugegeben, hier spielt die Performance so-gut-wie keine Rolle. Konzeptuell ist es aber das selbe. Man müsste nicht kopieren, muss aber doch. Oder man braucht Shared-Ownership.

    Oder wenn man multi-level (infinite-level) Undo implementieren will: eine Variante das zu machen ist mit Dokumenten zu arbeiten die mit "mittlerer" Granularität in Stücke aufgeteilt sind. Wobei die Stücke so gross sind dass es nicht zu sehr bremst und so klein dass nicht zu viel Overhead entsteht. Wenn man ein Dokumenten ändert, erzeugt man einfach ein neues mit 2-3 neuen Stücken und einer neuen Stückliste. Und die letzten paar, paar hundert (oder unendlich) behält man sich einfach in der Undo Liste. Ohne Sharing verbietet sich das auf Grund des Speicherbedarfs und oft auch auf Grund der Performance (komplexe riesen Dokumente zu kopieren braucht halt auch seine Zeit).

    Wobei die Anwendungen wo die Performance wirklich kritisch ist mit vielen vielen kleinen bis winzigen Objekten arbeiten, wie eben beim erwähnten XML Parser. Andere Parser werden aber vermutlich genau so betroffen sein, also speziell wenn man nen Browser damit entwickeln möchte ...

    Marthog schrieb:

    ownie schrieb:

    Es soll bald auch Gc<T> geben.

    Nicht mehr. Gc wurde nie vollstaendig implementiert, (...)

    Wieder schade.
    Ein GC im Sprachkern (zusätzlich zum deterministischen Gedöns ala C++) hat auch Vorteile wenn man hochperformante Programme schreiben will. Etliche lock-freie Datenstrukturen werden damit z.B. immens viel einfacher.
    Wobei ich diese Entscheidung noch eher verstehe. GC heisst immer dass Threads eingefroren werden müssen. Automatisch ist doof, weil nicht kontrollierbar, manuell ist doof, weils keinen schert immer wieder den GC aufzurufen - alles doof.
    Praktisch aber doof 😃



  • Zum einen kann man sehr gut generischen Code schreiben, der sowohl auf owning, als auch non-owning types funktioniert und zwischen diesen Typen notfalls auch konvertieren kann oder auf verschiedenen Arten von smartpointern bzw eigenen Typen arbeitet und es gibt es auch einen copy-on-write-pointer, der diese konvertierungen zur Laufzeit erledigt.
    Ansonsten muss man was selber schreiben. rustc verwendet statt kopien eine riesige Codemap mit geteiltem Zugriff und die Parser greifen dann hauptsaechlich auf Teile daraus zu.

    Statt garbage collector kann man in bestimmten Situationen die Datenstrukturen Arena und TypedArena, quasi pool allocator ohne free-list, die im Destructor ihren gesamten Speicher auf einmal freigeben und alle Destructors der alloziierten Objekte aufrufen. Die sind aber noch nicht richtig brauchbar, weil man noch keine eigenen allocator fuer collections angeben kann (wobei sich das auch nur bei der list lohnt).



  • Marthog schrieb:

    Statt garbage collector kann man in bestimmten Situationen die Datenstrukturen Arena und TypedArena, quasi pool allocator ohne free-list, die im Destructor ihren gesamten Speicher auf einmal freigeben und alle Destructors der alloziierten Objekte aufrufen.

    Dieser Satz ein Verb zu wenig 😃
    Aber wie funktioniert das dann mit Arena/TypedArena.
    Also wenn ich da Strings drinnen verwalten möchte.
    Wie bekomme ich den String dann da raus, ohne ihn kopieren zu müssen?

    Also angenommen mein XML Parser will ein Document zurückgeben, und das Document hat Trillionen Strings. In so einer Arena.
    Wie tu' ich da wenn ich "von aussen" einen DOM-Walk machen möchte? Oder muss ich den DOM-Walk als Funktor implementieren, so dass das Dokument den Funktor mit ausgeborgten Strings "zurückrufen" kann?
    Oder kann man sich vom Dokument auch "geborgte" Strings (und Notes und...) holen, so lange diese die garantierte Lifetime des Dokuments nicht "überschreiten"?

    Marthog schrieb:

    Ansonsten muss man was selber schreiben. rustc verwendet statt kopien eine riesige Codemap mit geteiltem Zugriff und die Parser greifen dann hauptsaechlich auf Teile daraus zu.

    Jo. Dass man was selbst schreiben kann ist klar. Das Problem dabei ist nur dass man es eben machen muss. Und dass dabei oft Dinge rauskommen die nicht so wirklich gut "interoperable" sind mit anderen Libraries/Frameworks/...



  • Eine Arena kann man wohl fuer strings nicht benutzen. Man kann aber sehr gut selber ein Byte-Array erzeugen und daraus dann jeweils string-slices zurueckgeben oder den Stringinterner aus dem rust-parser klauen. Die meisten libraries werden wohl soweit moeglich direkt auf diesen String-slices arbeiten koennen und nur wenn noetig eigenen Speicher reservieren.
    Allerdings ist es bei sowas ziemlich schwer, sicherzustellen, dass die lifetimes alle passen.
    Eine Funktion rekursiv durch den ganzen Baum zu schicken ist wohl das einfachste, aber nicht immer erweiterbar, cache-effizient und parallelisierbar.



  • hustbaer schrieb:

    krümelkacker schrieb:

    Wo siehst Du denn da Optimierungspotential?

    […]

    Nee, ich meine Optimierungspotential, welches angeblich unerschöpft bleibt, weil Rust und C++ nichts an „schlauen“ Zeigern (oder was auch immer) im Sprachkern drin haben. Da kann ich mir nämlich nicht so viel drunter vorstellen. Gut, Du hast die Behauptung aufgestellt, dass lockfreie Datenstrukturen mit GC ggf einfacher wären. Das habe ich so oder so ähnlich schon mehrfach gehört. Aber: Kennst Du dafür Belege? Würd' mich mal interessieren.



  • krümelkacker schrieb:

    Gut, Du hast die Behauptung aufgestellt, dass lockfreie Datenstrukturen mit GC ggf einfacher wären. Das habe ich so oder so ähnlich schon mehrfach gehört. Aber: Kennst Du dafür Belege? Würd' mich mal interessieren.

    Überall wo man ohne GC Hazard Pointer braucht geht's mit GC einfacher (und vermutlich auch performanter).
    http://en.wikipedia.org/wiki/Hazard_pointer



  • Jetzt ist die beste Zeit zu Rust zu wechseln, weil man sich jetzt noch in die Sprache einbringen kann.



  • Klartext schrieb:

    Jetzt ist die beste Zeit zu Rust zu wechseln, weil man sich jetzt noch in die Sprache einbringen kann.

    Noe. Mit der alpha 2 ist das meiste soweit stable. Beim meisten Kram kann danach nur noch hinzugefuegt, aber keine bestehende API mehr geaendert werden.



  • was ich mir von C++ in Zukunft wünsche sind ganz andere Sachen. Mit Speicherlecks, segmentation faults, exception-safety etc habe ich nämlich keinerlei Probleme. Ist u.a. eine Frage der systematischen Herangehensweise. Eine GC brauche ich nicht. Im Gegenteil, die Abwesehenheit einer solchen zwingt mich, von Anfang die wichtigen Fragen zu beantworten ("wen gehört diese Resource? - Wann wird sie freigegeben? ..." usw)

    aber das ABI - ich muß oft viel Zeit in Portabilitäts- und Interoperabilitätsfragen investieren: Object Formate, name mangling. Static linking. Aufrufformate. usw.

    Solche Probleme sind oft so knifflig, daß die eigentliche C++-Programmierung für mich fast schon wie Urlaub wirkt.

    Ich würde mir mehr Interoperabilität als extern "C" wünschen, aber es gibt ja bereits einen proposal für extern "abi". Vielleicht in C++14? C++17? Für mich ist so etwas jedenfalls bedeutend wichtiger als etwa eine GC.



  • großbuchstaben schrieb:

    Ich würde mir mehr Interoperabilität als extern "C" wünschen, aber es gibt ja bereits einen proposal für extern "abi". Vielleicht in C++14? C++17? Für mich ist so etwas jedenfalls bedeutend wichtiger als etwa eine GC.

    C++14 ist doch schon draußen und das nächste ist C++18.



  • großbuchstaben schrieb:

    was ich mir von C++ in Zukunft wünsche sind ganz andere Sachen. Mit Speicherlecks, segmentation faults, exception-safety etc habe ich nämlich keinerlei Probleme.

    Alle komplexeren C++-Projekte haben damit aber Probleme, weil Menschen eben Fehler machen. Gerade in diesen Hackerzeiten ist jeder Exploit einer zu viel.



  • großbuchstaben schrieb:

    Mit Speicherlecks, segmentation faults, exception-safety etc habe ich nämlich keinerlei Probleme. Ist u.a. eine Frage der systematischen Herangehensweise. Eine GC brauche ich nicht. Im Gegenteil, die Abwesehenheit einer solchen zwingt mich, von Anfang die wichtigen Fragen zu beantworten ("wen gehört diese Resource? - Wann wird sie freigegeben? ..." usw)

    Naja, zum Teil ist C++ in der Hinsicht selbstdokumentierend durch die Unterscheidung zwischen "RAII-Typen" und rohen Zeigern/Referenzen. Es gibt aber genug Stellen hier und da, wo man keinen Ownership-Transfer haben will, sondern irgend einem Fetzen Code eine Resource ausleihen will. Das wird spätestens dann fehleranfällig, wenn so eine Leihgabe dem Aufruf-Stack entflieht und z.B. in irgendeiner anderen Datenstruktur gespeichert wird. Du musst Dir in so einer Situation überlegen, wie Du garantieren kannst, dass diese Leihgaben nicht ungültig werden. Oder Du wechselst zu Shared-Ownership in solchen Situationen, um es schwieriger zu machen, Mist bzgl baumelnden Zeigern zu bauen. Shared ownership bringt aber auch seine eigenen Nachteile mit. Ich finde, da wo C++ mit RAII aufgehört hat, macht Rust mit dem „Borrowing“-Konzept weiter. Das ist eine Sache, die dem Compiler bekannt ist, weil es Teil des Typsystems ist. Dementsprechend gibt es einen „Borrow Checker“ im Compiler, der sicherstellt, dass es keine Baumelnden Zeiger gibt. Das ist mir lieber als in C++ darauf zu vertrauen, dass ich beim Design keinen Mist gebaut habe und doch zu lange an einem Zeiger festgehalten habe.

    Abgesehen davon, gibt es in Rust genug andere Nettigkeiten/Vereinfachungen gegenüber C++. Zum Beispiel ist das Design der Standardbibliothek vorbildlich. Du kannst eine HashMap<String, SonstWas> abfragen, ohne erst einen temporären String konstuieren zu müssen. Ein &str geht da z.B. auch, was die sichere Version von const char* oder string_view ist. Man muss sich auch nicht mit Dingen wie begin/end rumschlagen. Die Sache mit den Iteratoren ist in Rust sehr ergonomisch.

    Im Endeffekt ist Rust eine Sprache, die die guten Dinge aus diversen Sprachen zu übernehmen versucht, ohne dabei dieselben Fehler zu machen. Und im Vergleich zu dem, was es sonst noch so auf dem Markt in diesem Sektor der „Low-Overhead“-Sprachen gibt, ist ihr das IMHO gut gelungen. Ich weiß, das hört sich wahrscheinlich genauso an, wie das, was mir Leute erzählen, wenn sie mir erklären wollen, wie cool doch D ist. Das überzeugt mich nämlich nicht. Nicht soweit, dass ich D ausprobieren wollen würde. Damit will nur sagen, dass es Spracheigenschaften gibt, die man selbst erfahren muss. Und das beschränkt sich nicht nur auf Rust.

    Nachtrag: Was mir noch aufgefallen ist, dass Rust es mir erlaubt, ausgeliehene Referenzen wie „normale Werte“ zu behandeln. Diese Art der Referenzen kam mir erst sehr komisch vor und ich konnte mir nicht verkneifen, zu denken, dass das eine blöde Idee ist. Aber das sehe ich jetzt anders. In Rust kann man nichts falsch machen, wenn man eine Referenz stellvertretend als einen „Wert“ betrachtet – also auch im Sinne der Wertesemantik. Nicht nur ist die Sache mit der Lebenszeit des Dings, worauf sich so eine Referenz bezieht, kein Problem, sondern auch das Aliasing. Wenn die Aliasing-Regeln in Rust nicht so streng wären, würde es nämlich nicht funktionieren, so zu tun, als würden sich Referenzen wie Werte verhalten. Ich find' das extrem cool, weiß aber nicht, wie ich das richtig rüberbringen kann, so dass man mich auch versteht. 🙂



  • krümelkacker schrieb:

    Es gibt aber genug Stellen hier und da, wo man keinen Ownership-Transfer haben will, sondern irgend einem Fetzen Code eine Resource ausleihen will. Das wird spätestens dann fehleranfällig, wenn so eine Leihgabe dem Aufruf-Stack entflieht und z.B. in irgendeiner anderen Datenstruktur gespeichert wird. Du musst Dir in so einer Situation überlegen, wie Du garantieren kannst, dass diese Leihgaben nicht ungültig werden. Oder Du wechselst zu Shared-Ownership in solchen Situationen, um es schwieriger zu machen, Mist bzgl baumelnden Zeigern zu bauen. Shared ownership bringt aber auch seine eigenen Nachteile mit. Ich finde, da wo C++ mit RAII aufgehört hat, macht Rust mit dem „Borrowing“-Konzept weiter.

    👍 Sehr schoen gesagt, ich bin drauf und dran mal ein Projekt mit Rust zu schreiben, momentan habe ich nur eine grobe Idee der Sprache, aber alles was ich so gelesen habe hoert sich ziemlich gut an.


Anmelden zum Antworten