Ressourcenbedarf Programmiersprachen/Implementierungen



  • Sprachprogrammierer schrieb:

    Wieso bringen kleine Libraries weniger Overhead, solange du nicht dazu gezwungen wirst alle Funktionalitäten zu nutzen?

    Weil bei einer dynamisch gelinkten Library (so wie es sein sollte) die ganze Bibliothek in den Speicher geladen wird und nicht nur die Funktionen, die dein Programm gerade braucht.

    Besitzt beispielsweise Slicing einen besonderen Overhead gegenüber Pointerarithmetik?

    Was verstehst du unter Slicing?
    http://en.wikipedia.org/wiki/Program_slicing

    Hat C denn einen anderen Parametermodus als Copy by Value?

    Natürlich! Copy by Reference.
    Bzw. die Übergabe eines Zeigers auf eine Variable, Struct, Array usw.

    Hier besitzt wohl auch der Compiler einen gewissen Spielraum. Es braucht keine Kopie, wenn nicht auf der Variable geschrieben wird.

    Wenn der Compiler so schlau ist und in allen möglichen Fällen das erkennt, ja, dann kann er den Call by Value in einen Call by Reference umwandeln.



  • Michael E. schrieb:

    Hast du noch ein Beispiel, dessen letzte Version jünger ist als 20 Jahre?

    Ich habe mich noch nicht mit so vielen Sprachen befaßt, ich sehe da nämlich auch keinen großen Sinn, Hintlerwäldlersprache XY auch noch zu können.

    Die Sprachen mit denen ich mich befaßt habe (Pascal, C/C++, D, PHP, Java, Python), können alle, außer eben GW-Basic (meine 1. Progsprache), Call by Reference.



  • Wisser schrieb:

    Natürlich! Copy by Reference.

    Sry, es sollte heißen Call by Reference.



  • Wisser schrieb:

    Michael E. schrieb:

    Hast du noch ein Beispiel, dessen letzte Version jünger ist als 20 Jahre?

    Ich habe mich noch nicht mit so vielen Sprachen befaßt, ich sehe da nämlich auch keinen großen Sinn, Hintlerwäldlersprache XY auch noch zu können.

    Die Sprachen mit denen ich mich befaßt habe (Pascal, C/C++, D, PHP, Java, Python), können alle, außer eben GW-Basic (meine 1. Progsprache), Call by Reference.

    PS:
    Ok vielleicht noch QBasic.

    Damit hatte ich auch mal ne kurze Weile zu tun, aber da weiß ich es nicht wirklich wie das mit Call by Reference ist.



  • Wisser schrieb:

    Michael E. schrieb:

    Wisser schrieb:

    Andere Sprachen können gar keine Pointerarithmetik, im schlimmsten Fall können sie sogar bei Funktionsparametern nur Copy by Value

    Beispiel?

    GW -Basic

    Hat GW-Basic überhaupt Call-by-irgendwas? Da gibts doch nur GOSUB...RETURN ohne Parameterübergabe. Die einzige Form von Funktion ist DEF FN, aber da kann man nur Skalare übergeben.
    QBasic hatte dann schon ByRef, AFAIR. Ist das lange her ...



  • Java hat Call by Reference? Aha gut zu wissen 🙄



  • Wisser schrieb:

    Sprachprogrammierer schrieb:

    Wieso bringen kleine Libraries weniger Overhead, solange du nicht dazu gezwungen wirst alle Funktionalitäten zu nutzen?

    Weil bei einer dynamisch gelinkten Library (so wie es sein sollte) die ganze Bibliothek in den Speicher geladen wird und nicht nur die Funktionen, die dein Programm gerade braucht.

    Man muss aber nicht dynamisch linken und es wird auch oft nicht getan. Ob das so sein sollte ist Ansichtssache und hängt auch von der Situation ab.

    Wisser schrieb:

    Was verstehst du unter Slicing?
    http://en.wikipedia.org/wiki/Program_slicing

    Ich meinte Array Slicing:
    http://en.wikipedia.org/wiki/Array_slicing

    Wisser schrieb:

    Hat C denn einen anderen Parametermodus als Copy by Value?

    Natürlich! Copy by Reference.
    Bzw. die Übergabe eines Zeigers auf eine Variable, Struct, Array usw.

    Das ist streng genommen die Übergabe eines Pointers per Value. Damit lässt sich ein pass by reference simulieren, aber es ist keine unterstützte Eigenschaft der Sprache. Das ist sogar eines dieser Fälle, wo eine höhere Abstraktion Overhead vermeiden kann. Wenn ein Parametermodus unterstützt wird der unterschiedlichen Zugriff auf den tatsächlichen Parameter erlaubt, kann der Compiler entscheiden wie er es umsetzt.

    Ich habe aber zumindest verstanden was du meinst und da hast du durchaus Recht. Ich habe mich zugegebenermaßen noch nie mit einer Sprache beschäftigt, bei der das Problem existiert.



  • die Frage "was ist wichtiger - a) der Algo oder b) seine Implementierung" kann man nicht mit "a)" oder "b)" beantworten, das hängt vom Einzelfall ab.

    Beispiel:

    Laufzeit des Algorithmus A auf einer abstrakten Maschine (Turing- oder Register- oder ...) 
    
    ~ 2^n
    
    Implementierung von A, sagen wir: 
    
    10*2^n auf einer echten CPU.
    
    Laufzeit des Algo B auf der selben abstrakten Maschine 
    
    ~ n^2
    
    Implementierung von B, angenommen: 
    
    1000*n^2 auf echter CPU.
    

    Asymptotisch und in der Theorie ist B der klar bessere Algo.

    Frage: Was ist in der Praxis besser, A oder B?

    Antwort: Das hängt von der Eingabgröße ab.

    Bis Eingabegröße n = 14 ist hier Implementierung von A besser, ab Eingabegröße n >= 15 ist die Implementierung von B besser.

    Also:

    obwohl B klar der bessere Algo ist, ist für Eingaben bis Größe 14 die Implementierung von A effizienter.

    Wäre man sicher, daß alle praxisrelevanten Eingaben n <= 14 erfüllen, wäre hier die Implementierung des schlechteren Algo die bessere Wahl.



  • Ich verstehe gar nicht, warum ihr dieses Zitat alle so unterstützt? Dieses Zitat ist eine einzige Verallgemeinerung. Und wenn ich jetzt anfange eine Sprache zu entwickeln, die gewisse Dinge konzeptbedingt nicht bietet, dann lassen sich auch gewisse Dinge schlechter implementieren, während andere Dinge sich besser implementieren lassen.

    Man kann damit also sagen, dass es Sprachen gibt, die für gewisse Dinge eher geeignet sind. Folglich ist es falsch immer zu sagen, dass der Programmcode schlecht ist. Viel mehr liegt es an der Sprache.

    Und wenn ihr so Annahmen macht von wegen "Programmiersprachen als abstraktes Gebilde", dann entspricht das nicht mehr der Realität. Und es ging um die Realität und nicht irgendwelchen theoretischen Ansätzen. In der Realität macht es eben einen Unterschied, welche Sprache man nimmt. Man kann mit einigen Sprachen bessere Ergebnisse erzielen, als mit anderem. Das lässt sich sogar auf menschlische Sprachen beziehen. Auch hier gibt es unterschiedliche Stärken.



  • DuWeißtGarNix schrieb:

    Java hat Call by Reference? Aha gut zu wissen 🙄

    Bei Objekten hat es das.
    Das bedeutet also nicht, daß es dies gar nicht hätte.
    http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html

    Java ist halt eingeschränkt.



  • Sprachprogrammierer schrieb:

    Man muss aber nicht dynamisch linken und es wird auch oft nicht getan. Ob das so sein sollte ist Ansichtssache und hängt auch von der Situation ab.

    Es sollte so sein, wenn einem die Bibliothek nicht gehört.

    Ja, dann sollte man aus Sicherheitsgründen nicht statisch linken.
    Sondern nur dynamisch, damit man die Bibliothek mit Sicherheitslücke gegen eine ohne Sicherheitslücke austauschen kann.

    Wisser schrieb:

    Was verstehst du unter Slicing?
    http://en.wikipedia.org/wiki/Program_slicing

    Ich meinte Array Slicing:
    http://en.wikipedia.org/wiki/Array_slicing
    [/QUOTE]
    Ok, zu deiner Frage, keine Ahnung Array Slicing benutze ich als vorwiegend C Progger nicht.



  • Wisser weißmehralsdu schrieb:

    DuWeißtGarNix schrieb:

    Java hat Call by Reference? Aha gut zu wissen 🙄

    Bei Objekten hat es das.

    Vielleicht solltest du den Link auch mal lesen, den du grade gepostet hast 🙂



  • ,,,, schrieb:

    Ich verstehe gar nicht, warum ihr dieses Zitat alle so unterstützt? Dieses Zitat ist eine einzige Verallgemeinerung.

    Es ist aber auch eine gute Faustregel. Selbst innerhalb einer Sprache gibt es zig Wege die Implementierung zu vermasseln, von daher macht es Sinn, dass man sich zunächst auf abstrakterer Ebene mit dem Problem befasst. In der Regel ist es dann schon 'schnell genug'. Wer noch etwas optimieren möchte, der kann dann die Stellen finden, an denen es hakt und gezielt optimieren. Oft ist die langsame Implementierung auf Unerfahrenheit mit den Sprachkonzepten zurückzuführen, nicht auf die Sprache an sich. Und wenn man dann wirklich noch den letzten Faktor rausbekommen will, dann kann man sich Gedanken um die Sprache machen und zumindest die kritischen Teile in was schnellerem implementieren. Natürlich macht es aber auch schon vorher Sinn sich Gedanken über die Sprache zu machen. Wissenschaftliches Rechnen (z.B. FEM) mit Java z.B. macht so gut wie keiner. Das scheint wohl die falsche Sprache für so etwas zu sein, wenn es schwer ist wenigstens halb so schnell wie C-Code zu werden. Wenn ich also eh große Teile in was anderem schreiben werde, dann kann ich auch gleich was anderes nehmen. Was ich bisher von Python gesehen habe, gefällt mir da im Ansatz ganz gut, da es einem wirklich einfach gemacht wird kritische Teile in C-Codes auszulagern. In meinem Bereich gibt es für C++ die besseren Bibliotheken, von daher wird mir die Sprachwahl ziemlich einfach gemacht ;).



  • Ich denke darüber diskutiert, wann Optimierungen eine Rolle spielen, haben wir bereits in anderen Threads genug. Genauso weiß auch Jeder, dass es entscheidend ist, was der Programmierer mit der Sprache anfängt. Was mich interessieren würde, sind Spracheigenschaften, die generell einen Overhead produzieren und nur schwer oder sogar gar nicht vom Programmierer oder dem Compiler/Interpreter umgangen werden können. Natürlich sind auch die technischen Details sowie der Sinn hinter diesen Spracheigenschaften und Alternativen dazu interessant.

    Es geht mir dabei auch nicht ausschließlich um "schnell", sondern ebenfalls um Größe im Hauptspeicher. Und es geht ganz und gar nicht um "schnell genug oder nicht schnell genug".



  • Ich glaube das führt zu nichts.
    Spracheigenschaften führen doch nicht zu Overheads. Eine Sprache hat im eigentlichen Sinne zunächst nichts mit Computern zu tun, sondern ist nur eine Menge von Wörtern, die weder schnell, noch langsam sein kann.

    Du interessierst dich hier eher für die Implementierungen einer Sprache. Die Sprache gibt nicht vor, wie etwas in Maschinencode umgesetzt werden soll, sondern nur, was als Ergebnis passieren soll. Und egal welche Sprache du nimmst, unterm Strich arbeiten sie mit Pointern, Speicherbereichen, Interupten, Subroutinen, den Speicherbereichen etc.
    In den Sprachen findest du m.M.n. nicht die "Quelle der Langsamkeit".

    Was spricht dagegen, Java als Maschinen-Sprache ohne VM zu implementieren?



  • Nichts, aber trotzdem kann ja Overhead bleiben.

    Eine Programmiersprache ist eine Sprache, die nicht das Ergebnis, sondern den Programmablauf beschreibt. Zumindest gilt das für imperative Programmiersprachen. Ein Compiler, der sich an das hält, was der Programmierer geschrieben hat, so dass der Programmierer sich auch darauf verlassen kann, dass das passiert, was er erwartet, besitzt nun einmal Einschränkungen. Um tatsächlich in zwei völlig unterschiedlichen Sprachen den exakt gleichen und optimalen Maschinencode zu erhalten, müsste der Compiler genau wissen, wie das Ergebnis aussehen soll. Das kann er nicht. Er setzt das um, was der Quelltext ihm vorsetzt.

    Natürlich kann er theoretisch beliebig weit optimieren und ein optimales Ergebnis liefern. Aber das tun derzeitige Implementierungen doch nicht mal annähernd.

    Nehmen wir doch mal mit Forth ein einfaches Beispiel. Ein Forth-Programm besteht ausschließlich aus der Aneinanderreihung von Anweisungen. Der Compiler sieht also Anweisungen. Diese Anweisungen führen zu einem Ergebnis, einer Software. Glaubst du wirklich, irgendein Compiler ist, oder wird in absehbarer Zukunft, so intelligent sein, dass er aus einer Million dieser Anweisungen den Sinn, Zweck und das Ziel des Programms versteht um daraus optimalen Maschinencode zu erstellen? Theoretisch ist das Möglich, da im Programm beschrieben wird, was als Ergebnis passieren soll, aber das ist doch für den Compiler absolut nicht greifbar.



  • Die Compiler-Optimierungen sind schon längst ziemlich genial. Man sehe das mal so: Overhead kommt durch schlechte/redundante Maschinenbefehle, die wiederrum kommen aus dem Compiler. Eine Programmiersprache ist nicht an den Maschinencode gebunden, den der Compiler aus der Sprache macht. Die Sprache folgt einer wohl definierten Grammatik, die der Compiler über Parsebäume auflöst und dabei den Code generiert. Was er da generiert hat nichts mit der Sprache zu tun.

    Am Ende ist es also die Fähigkeit des Compilerbauers und des Programmierers. Sprachen machen es hierbei nur schwerer o. einfacher, sie performant in Maschinencode um zu setzten. Jedenfalls denke ich, dass es einfacher ist, C++ Code zu optimieren als z.B. Erlang-Code, der in der Theorie der Maschine weiter entfernt ist.



  • Ad aCTa schrieb:

    Ich glaube das führt zu nichts.
    Spracheigenschaften führen doch nicht zu Overheads. Eine Sprache hat im eigentlichen Sinne zunächst nichts mit Computern zu tun, sondern ist nur eine Menge von Wörtern, die weder schnell, noch langsam sein kann.

    Du interessierst dich hier eher für die Implementierungen einer Sprache. Die Sprache gibt nicht vor, wie etwas in Maschinencode umgesetzt werden soll, sondern nur, was als Ergebnis passieren soll. Und egal welche Sprache du nimmst, unterm Strich arbeiten sie mit Pointern, Speicherbereichen, Interupten, Subroutinen, den Speicherbereichen etc.
    In den Sprachen findest du m.M.n. nicht die "Quelle der Langsamkeit".

    Was spricht dagegen, Java als Maschinen-Sprache ohne VM zu implementieren?

    Nichts, aber wir bewegen uns leider in der Realität, und da rechnen wir mit Implementierungen und nicht mit Gedankenkonstrukten.


  • Mod

    Stimmt, gewisse Dinge machen nur im Zusammenhang begutachtet Sinn. Manche Sprachen lassen sich leicher lernen und verstehen, und man kann auf diese Weise effizienteren Code hinbekommen. Man braucht hier und da weniger Texte oder Zeit, um leistungsfähige Programme zu schreiben, muss nicht so lange nach bestimmten Lösungen suchen, es gibt opensource und Beliebtheit etc.

    Manche Sprachen kosten Geld, um sie auszuprobieren, andere gibt es fast geschenkt.

    Manche Sprache stiften viel Verwirrung und kosten Zeit, andere weniger.

    Man kann dieses Thema nicht sinnvoll diskutieren, ohne sich über Betriebsystem und dessen Schnittstellen und Entwicklungstools Gedanken machen.

    Man kann dieses Thema nicht sinnvoll diskutieren, ohne sich über die Hardware und Hardwarestrukturen Gedanken zu machen, und über aktuelle Bedürfnisse und Marktmechanismen (und "Treiber").

    Basic und Assembler sind aus dem Mainstream verschwunden, weil es kaum noch Schnittstellenförderung in diesem Sinne gab, schlechte komplizierte Programmiersprachen waren sie nicht, fast jeder konnte auf Anhieb (mit Hilfe der Manuals damals) mit Basic und Assembler spielen.

    Man bräuchte eigentlich in Windows gar keine Programmiersprache mehr, ein gut geschriebener, Maus- und Tastaturfreundlicher Wizard, der auf optimierte Routinen zurückgreifen kann, bestimmte Dinge aus dem Internet nachladen kann (etwa bestimmte Algorithmen, Grafiken oder Sounds)(usw) würde vollkommen reichen.



  • Ad aCTa schrieb:

    Die Compiler-Optimierungen sind schon längst ziemlich genial. Man sehe das mal so: Overhead kommt durch schlechte/redundante Maschinenbefehle, die wiederrum kommen aus dem Compiler. Eine Programmiersprache ist nicht an den Maschinencode gebunden, den der Compiler aus der Sprache macht. Die Sprache folgt einer wohl definierten Grammatik, die der Compiler über Parsebäume auflöst und dabei den Code generiert. Was er da generiert hat nichts mit der Sprache zu tun.

    Am Ende ist es also die Fähigkeit des Compilerbauers und des Programmierers. Sprachen machen es hierbei nur schwerer o. einfacher, sie performant in Maschinencode um zu setzten. Jedenfalls denke ich, dass es einfacher ist, C++ Code zu optimieren als z.B. Erlang-Code, der in der Theorie der Maschine weiter entfernt ist.

    Sprachen machen es schwerer oder leichter, aber wie sieht es denn mit Sprachkonstrukten aus, die es beinahe unmöglich machen? Wie schon als Beispiel genannt: Wenn ich einen Rohdatenbedarf habe, sagen wir mal 20.000 Integer, benötige jetzt aber für dynamische Typisierung oder Reflection oder einfach garantiertes RTTI noch Typinformationen für jeden dieser Integer, muss mir deren Zustand im Speicher merken für Garbage Collection und habe die Integer, von der Sprache garantiert, als Referenzen auf dem Heap angelegt. Dies Alles wird dir garantiert von der Sprache, also darf die Implementierung absolut nicht diese Garantien brechen, solange sie sich nicht absolut sicher sein kann, dass sich kein einziger Teil der Software auf diese Daten verlässt. Das wird spätestens bei der Berücksichtigung von Reflection ziemlich kompliziert. Kann ein moderner Compiler, nicht nur theoretisch sondern auch praktisch, diese Dinge ausbügeln?

    Wenn ein Compiler beinahe beliebig aus dem von der Sprache und Quelltext gegebenen Bedingungen perfekten Code generieren kann, wieso spielt dann Performanz durch die Wahl des falschen Algorithmus noch eine Rolle? Er müsste doch auch hier die Auswirkung des Algorithmus erkennen und optimierten Maschinencode ausspucken.

    Wieso spielt Mikrooptimierung überhaupt noch eine Rolle?
    http://en.wikibooks.org/wiki/Ada_Style_Guide/Improving_Performance

    Ich kann mir gut vorstellen, dass moderne Compiler bereits sehr guten Code generieren und sehr intensive Optimierungen durchführen können. Aber absolut vom eigentlichen Quelltext und von der Sprache unabhängig die Software als Ganzes erkennen?

    Theoretisch sicher möglich, aber wenn es praktisch ebenso möglich ist, wieso wird es denn nicht getan?


Anmelden zum Antworten