Ressourcenbedarf Programmiersprachen/Implementierungen



  • Moin,

    Wer kennt diese Aussage nicht: "Programmiersprachen haben keinen Einfluss auf die Performanz von Software. Es sind die Programmierer, die die Software schreiben und erst in zweiter Linie die Implementierungen. Nicht aber die Programmiersprachen."

    So weit klingt es ja auch richtig. Der Softwareentwickler ist für das Endprodukt verantwortlich, seine Arbeit allein entscheidet über die Qualität und Eigenschaften der Software. Spielen aber die Werkzeuge die er dazu verwendet nicht eine sehr große Rolle? Bibliotheken, Compiler und eventuell auch Programmiersprachen selbst haben doch einen großen Einfluss auf das Produkt. Immerhin füttert er den Compiler oder Interpreter am Ende nur mit Informationen, das eigentlich Produkt generiert der Compiler oder Interpreter selbst.

    Der Compiler muss mit den Informationen leben, die ihm der Programmierer gibt und er muss sich dabei exakt an die Regeln der Programmiersprache halten, damit die Verständigung mit dem Programmierer auch funktioniert.

    Programmiersprachen können viele Dinge garantieren und fordern. Kann eine Implementierung wirklich so weit das vom Programmierer beschriebene Programm abstrahieren und das Ergebnis komplett unabhängig machen von der Programmiersprache?

    Aus mathematischer Sicht wohl schon. Man sieht das Programm als eine Art von hochkomplizierter mathematischer Formel oder eine Menge solcher Formeln und in der Mathematik zählt nur das Ergebnis, das korrekt sein muss. Verschiedene Beschreibungen, die unterschiedlich kompliziert sind, sind äquivalent und austauschbar, solange sie immer zum gleichen Ergebnis führen. Eine Implementierung könnte also das Problem, das der Programmierer zu lösen versucht verstehen und so einen optimalen Lösungsweg generieren.

    Da gibt es aber zwei Probleme: Zum Einen ist ein Computerprogramm kein mathematischer Ausdruck. Ein Mathematischer Ausdruck "ist einfach wahr", während ein Computerprogramm aus einer Reihe von Operationen besteht und "etwas tut". Mathematische Modelle in der Softwareentwicklung sind ein gutes und nahezu unverzichtbares Hilfsmittel, man muss aber vorsichtig sein, wie man sie anwendet. Zum Anderen müsste eine Implementierung, die das Problem exakt und komplett begreifen kann um aus diesem Wissen die optimale Software zu generieren eine Intelligenz besitzen, die Programmierer beinahe überflüssig zu machen scheint.

    Welchen Overhead müsste so eine Implementierung ausbügeln können, um tatsächlich die verwendete Programmiersprache in Sachen Ressourcenbedarf gleich zu schalten? Wenn man sich beispielsweise Python anschaut, sieht man dort viele Garantien und Forderungen der Sprache, die Overhead im Speicherbedarf produzieren:
    - Alle Objekte werden durch einen Pointer referenziert
    - RTTI für jedes Objekt
    - Garbage Collection benötigt Informationen über den Zustand dynamisch angeforderter Objekte. Da in Python alle Objekte dynamisch auf dem Heap angelegt werden, entsteht wieder ein Overhead, der sich von Seiten des Programmierers nicht umgehen lässt.

    Natürlich könnte eine gute Implementierung diesen Overhead zumindest teilweise dort ausmergeln, wo beispielsweise Typinformation gar nicht abgefragt wird. Typinformation ist aber unerlässlich für dynamisch typisierte Programmiersprachen und zudem verhindern ebenfalls garantierte Funktionalitäten wie Reflection, dass man eine spätere Verwendung jedweder "Garantien" ausschließen und damit herausoptimieren kann.

    Wie viel Praxis steckt in der Theorie, dass Programmiersprachen keine Auswirkungen auf den Ressourcenbedarf der generierten Software hat, abgesehen von der Verwendung eventuell Ressourcenintensiver Idiome?



  • Ich denke, dass diese Theorie so nicht haltbar ist. Natürlich hat der Programmierer einen gewissen Einfluss auf den Ressourcenbedarf, aber letztendlich gibt es einen Punkt, wo dieser nicht mehr unterboten werden kann. Das Limit liegt hier bei der Sprache oder den dazugehörigen Programmen selber.

    Wobei eine interpretierte und compilierte Sprache sich im Ressourcenbedarf natürlich schlecht vergleichen lassen. So ist es klar, dass Java einen viel höheren Ressourcenbedarf besitzt, als es ein C++ Programm tut.

    Da aber Java trotzdem auch eine Programmiersprache ist, ist an dieser Stelle die Theorie schon widerlegt. Denn die Sprache selber setzt hier einen Ressourcenbedarf an den Tag auf den der Programmierer keinen Einfluss mehr hat. Ohne den Interpreter ist das Programm schließlich nicht funktionsfähig.

    Bei einer kompilierten Sprache sieht das etwas anders aus. Aber auch hier spielen dann der Compiler, Optimierungslevel und ähnliches eine Rolle. Es ist halt auch die Frage was alles zur Sprache gehört. Gehört der Compiler bereits zur Sprache? Gehört der Interpreter zur Sprache?

    Wenn man das alles verneinen kann, dann kann man vielleicht sagen, dass der Programmierer dafür eher verantwortlich ist. Obwohl einige Sprachen ja nun auch gewisse Strukturen vorschreiben, was sich spätestens dann eindeutig der Sprache zuschreiben lässt. Beispielsweise C# mit der OOP-Pflicht. Oder Sprachen, die auf Sicherheit getrimmt sind oder daher mehr Ressourcen benötigen, um die Gültigkeit der Operationen in diesem Kontext zu überprüfen. Dies trägt sicher auch zu einem erhöhten Ressourcenbedarf bei.

    Ich denke, es ist egal wie man es dreht und wendet. Die Aussage ist unhaltbar. Die Sprache spielt eine entscheidende Rolle und erst danach kommt der Programmierer.

    Es handelt sich hierbei nur um meine spontane eigene Meinung.



  • ,,,,, schrieb:

    Die Sprache spielt eine entscheidende Rolle und erst danach kommt der Programmierer.

    Zuerst kommt der Programmierer, wenn der Mist baut und nur Bubblesort & Scriptsprachen wie Basic benutzt, dann kann das nix werden.

    Dann kommen die Algorithmen, ein guter Algo bringt mehr als eine gute Sprache.

    Aber zum Schluß kommen dann trotzdem die Sprachen, denn nicht jede Sprache bietet den gleichen Funktionsumfang. Dieser ist aber in mancher Hinsicht entscheident.

    C ist z.B. so effizient, weil es Pointerarithmetik erlaubt und selbst bezügl. der Librarys wenig Ballast mitbringt.
    Andere Sprachen können gar keine Pointerarithmetik, im schlimmsten Fall können sie sogar bei Funktionsparametern nur Copy by Value, das lahmt alles.



  • Sprachprogrammierer schrieb:

    "Programmiersprachen haben keinen Einfluss auf die Performanz von Software. Es sind die Programmierer, die die Software schreiben und erst in zweiter Linie die Implementierungen. Nicht aber die Programmiersprachen."

    Das stimmt so, wenn man die Programmiersprache als abstraktes Gebilde sieht. Compiler und Interpreter übersetzen nur Texte, die den Regeln der Programmiersprache entsprechen (sollen).

    Wisser schrieb:

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

    Beispiel?



  • 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



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



  • ,,,,, schrieb:

    Bei einer kompilierten Sprache sieht das etwas anders aus. Aber auch hier spielen dann der Compiler, Optimierungslevel und ähnliches eine Rolle. Es ist halt auch die Frage was alles zur Sprache gehört. Gehört der Compiler bereits zur Sprache? Gehört der Interpreter zur Sprache?

    Der Compiler oder Interpreter gehört nicht direkt zur Sprache, aber natürlich beeinflusst die Sprache die Eigenschaften von Compiler und Interpreter.

    ,,,,, schrieb:

    Wenn man das alles verneinen kann, dann kann man vielleicht sagen, dass der Programmierer dafür eher verantwortlich ist. Obwohl einige Sprachen ja nun auch gewisse Strukturen vorschreiben, was sich spätestens dann eindeutig der Sprache zuschreiben lässt. Beispielsweise C# mit der OOP-Pflicht. Oder Sprachen, die auf Sicherheit getrimmt sind oder daher mehr Ressourcen benötigen, um die Gültigkeit der Operationen in diesem Kontext zu überprüfen. Dies trägt sicher auch zu einem erhöhten Ressourcenbedarf bei.

    Ich kenne an Sprachen die auf Sicherheit getrimmt sind nur Ada. Da kann ich nicht beobachten, dass viele Funktionen verpflichtend sind, die einen Overhead produzieren. Auch die Laufzeitüberprüfungen sind abschaltbar.

    Was verursacht denn in C# (oder auch in Java) im Hinblick auf "OOP-Pflicht" so einen großen Overhead?

    Wisser schrieb:

    ,,,,, schrieb:

    Die Sprache spielt eine entscheidende Rolle und erst danach kommt der Programmierer.

    Zuerst kommt der Programmierer, wenn der Mist baut und nur Bubblesort & Scriptsprachen wie Basic benutzt, dann kann das nix werden.

    Also spielt die Sprache (Hier Basic) nun doch eine primäre Rolle?

    Wisser schrieb:

    C ist z.B. so effizient, weil es Pointerarithmetik erlaubt und selbst bezügl. der Librarys wenig Ballast mitbringt.
    Andere Sprachen können gar keine Pointerarithmetik, im schlimmsten Fall können sie sogar bei Funktionsparametern nur Copy by Value, das lahmt alles.

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

    Besitzt beispielsweise Slicing einen besonderen Overhead gegenüber Pointerarithmetik?

    Hat C denn einen anderen Parametermodus als Copy by Value? Hier besitzt wohl auch der Compiler einen gewissen Spielraum. Es braucht keine Kopie, wenn nicht auf der Variable geschrieben wird.



  • 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 ;).


Anmelden zum Antworten