Je weniger Code desto besser?

Pippen123 schrieb:
Mein naiver Hingergedanke ist: jeder Befehl kostet Zeit und Ressourcen, d.h. je weniger desto besser
Das ist zu oberflächlich. Eine Addition braucht zum Beispiel 1 Takt, Multiply 4-6 Takte, Division bist du bei 30 Takten etwa und sqrt oder Trigonometrische Funktionen sind auch bei mehr als 100 Takten.

Dann musst du aber auch Bedenken das Memory Load/stores viele Takte brauchen. Wenn man Cache blocking einfügt wird der Code teils deutlich länger aber auch deutlich performanter.

Dann muss man auch schauen was die eine Arch man hat. Inorder vs out of order. Bei GPUs ist es zum Beispiel öfters sinnvoll stumpf alles zu berechnen und das nicht gebrauchte zu verwerfen anstatt mit controll Flow das zu verhindern.

BeBur schrieb:
Das überzeugt mich nicht so richtig, viele Programme bestehen nicht zum überwiegenden Teil aus komplexen oder aufwendigen selbstgebauten Algorithmen. Wer eine Such- oder Sortierfunktion selber implementiert, der macht höchstwahrscheinlich sowieso schon was grundlegend falsch.

Ich würde vermuten, du hast kürzlich AuD im Studium gehört? :p
Oft wirst du Recht haben, aber gerade wenn man z.b. drölf Millionen Listen mit jeweils nur 16 Werten sortieren muss, also oft kurze Arbeiten erledigen muss, hat man gut Chancen mit dem eigenen Code schneller zu sein.

Auch sinnvoll ist es wenn man zum Beispiel gewisse Charakteristika eines Problems ausnutzen kann. Z.b. wenn die ersten 5 Elemente die Eigenachaft XY haben, dann sind die nächsten 1Mio schon sortiert.

Das ist halt immer Domänenwissen was sehr hilfreich ist um jede Standardlösung zu schlagen.

Und so kann man viele Beispiele finden. Aber ja, der Großteil des geschriebenen Codes fällt nicht unter solche Fälle.


BeBur schrieb:
Das ist eine etwas seltsame Aussage in mehrerlei Hinsicht. Moderne Compiler wirst du imHo selten schlagen was reine Code-Optimierung angeht. Compiler verkürzen Code darüber hinaus auch nicht (zwangsläufig). Zumindest LLVM transpiled erst in IR vor dem Optimieren, also verkürzt "den code" selber gar nicht. Darüber hinaus schrieben hier ja schon mehrere, dass ein Grund für kompakten Code die Verständlichkeit ist und das hat mit Compilern nichts zu tun.
Moderne Compiler kannst du ganz einfach schlagen. Du musst nur ein Wissen über ein Problem aus seinem Scope schieben. Also z.b. durch verschieben in eine andere Datei oder durch Abhängigkeit von Usereingaben usw usf.

Man kann z.b. auch den ich recht einfach das Genick brechen so das er nicht mal mehr sieht das eine Funktion nicht mehr als +1 macht.... selbst beim ifort habe ich das gesehen. Und das nicht mal bei dynamischen Linken sondern statisch gelinkt.

Compiler können einfache Beispiele extrem gut lösen. In ner Übungsgruppe hatte nen Compiler zum Beispiel mal gesehen, dass die Berechnung statisch ist und den Wert dann eben zur Compilezeit berechnet. Hat dann 30 Minuten gedauert zu compilieren und der Code war am Ende aber <Faktor 2 schneller als der Code der es wirklich berechnet hat. Aufgefallen ist es, weil uns das Spanisch vorkam und wir sowohl mal die Anzahl instruktionen nachgerechnet haben die nötig sind und die maximal ausgeführt werden konnten in der Zeit und eben uns den Assemblercode am Ende angeschaut haben.

Und damit kommen wir zu nem wichtigen Punkt. Code muss immer angemessen sein und man darf KEIN Pattern stumpf durchziehen. Einmal Code braucht man zu 99% keiner Komplexitätsanalyse unterziehen. Es passiert aber auch mal, dass die grobe Abschätzung 4 Wochen Laufzeit ergibt. Dann muss man sich auch da Gedanken machen.

Pre optimization is the root of all evil. Ja stimmt, aber wenn ich Programm XY neu schreibe weil es zu langsam ist, dann MUSS ich mir vor der ersten Zeile ernsthaft Gedanken über die Datenstruckturen etc machen.

Und so geht es genau weiter. Man sollte aber natürlich nicht wahllos optimieren, es sei denn man weiß wirklich das etwas relevant ist für sie Laufzeit. Man sollte sich aber klar machen, das >95% der Entwickler total auf dem Holzweg bei solchen Einschätzungen sind... man muss das wirklich lernen und immer und immer und immer wieder kontrollieren durch Profiler und eben so Dinge wie roofline model.

Aber das ist immer alles sehr speziell wenn man ehrlich ist. Deswegen immer schauen, dass die Lösung angemessen ist. Ich hasse zum Beispiel mist den tertiären Operator. Oder wenn die Leute ganz fancy Sprachfeatures nutzen. Ich sag nur überladen der mathematischen Operaroren in C++... wenn du nicht mehr weißt was ein + ist, dann wird es extrem häßlich zu verstehen warum und wo ein Code Zeit verbrät und schlecht geschrieben ist.
 
  • Gefällt mir
Reaktionen: Quonux
fgordon schrieb:
Progammieren wird erst doch dann wirklich interessant, wenn es auch über das hinausgeht was jeder kann, Sachen von anderen aneinanderreihen.
This. :daumen:

Und ich vermute, durch diesen Ansatz bin ich inzwischen etwas "vergiftet" auch was meine Argumentation(en) zum Thema angehen. Denn gefühlt jeder Code, der nicht von mir stammt und mit dem ich aber was anfangen muß, ist eben solcher aneinandergereihter Code, der bei mir pauschal unter "Batch" zusammengefaßt ist, egal welche Sprache das war.

Abstraktionen sind nochmal ein eigenes Thema. Die blasen den Code ebenfalls auf, wie ja schon erwähnt wurde, aber machen ihn eben auch wiederverwendbar(er). Und dann gibt es da noch die logische Trennung von Codefragmenten nach Aufgabe im Code, die selbst auch aufblasen kann und die aber z.B. durch Objektorientierung "erforderlich" wird.

Ich kann Input, putput und Output in eine gemeinsame Schleife stecken. Code kürzer.
Oder ich kann das nach Input, Putput und Output auftrennen. Dann habe ich drei Schleifen und längeren Code.
Oft genug will ich aber zwei der drei Prozeßteile nicht immer mitnehmen (müssen). Dann brauch ich die drei getrennten Routinen. Aber die Zusammenfassung in eine gemeinsame will ich vielleicht nicht haben wegen DRY und jetzt noch Gehirnmasse investieren in Richtung "wie bau ich den Mist so, daß ich nur eine Schleife brauch für zwei oder mehr Aspekte gemeinsam, ohne daß ich mich wiederholen muß" kann und will ich aber vielleicht nicht.

Und schon haben wir ein gewisses Dilemma, was bereits in Richtung sunken cost abdriftet.

Aber vor demselben Atemzug? Wenn mein Entwickler der Meinung ist, nicht "for i = 1 to 1000 do echo i done" zu sagen, sondern "echo 1, echo 2, echo 3, ... echo 1000" stur eins nach dem anderen zu kopieren und einzufügen... dann dauert das Zeit für diesen Entwickler, dauert Zeit für die Wartung/Anpassung, dauert Zeit für Debugging (weil der Bursch irgendwo falsch kopiert/eingefügt hatte) und so weiter.

DIESE Kosten sind nicht minder versunken. Da braucht der vielleicht einen Arbeitstag für und nicht, wie man erwartet hätte, fünf Minuten.
 
Komisches Thema. Python ist 300mal langsamer als C.
Abseits von anderen Problemen die Python hat, in der heutigen Zeit mal die gesellschaftliche Frage, ob man, wenn man Glühbirnen mit 10%(?) Lichtausbeute verbietet, man nicht Python und co. verbieten sollte bzw. deren JIT-Interpreter.
Strom wächst nicht auf Bäumen, es sei denn man verbrennt sie und nutzt Wasserdampfturbinen.

So als Vergleich dazu, ob ich jetzt "in meiner Main" 10 Zeilen sehe, oder 20.
 
@Wasserhuhn
Deswegen nutzen die Leute die halbwegs ihr Handwerk verstehen jene Teile die Rechenzeit brauchen auch in gegen numby bzw. andere Bibliotheken/APIs die deutlich schneller sind. Vanilla Python sollte im Regelfell nur nur Clue Logik sein, die mit allen I/O-Warterien und Ausnahmebehandlungen auch mit C keine großen Effizienzgewinne zulässt.
 
Piktogramm schrieb:
Deswegen nutzen die Leute die halbwegs ihr Handwerk verstehen
Meh.

Ich muss dazu sagen, wie viele Leute nutzen Python, die deiner Meinung nach nicht ihr Handwerk verstehen, und wie viel macht das aus?
Ich bleibe dabei, dass extrem viel langsamer Code läuft, der Ressourcen verschwendet. Jetzt mal abseits von Kryptowährungen.
Wenn man sowas nutzen will, sollte es geläufigere Optionen geben, damit der Nutzer nichts davon mitbekommt, aber trotzdem energiesparenden Code hat.

Ich muss aber zugeben, seit ich für mich batteriebetriebenene Microcontroller nutze, habe ich eine etwas andere Perspektive als davor.
 
@Wasserhuhn
Och die Diskussion über langsame Programmiersprachen und langsamen Code ist soooo alt. Ganz realistisch überwiegen Designentscheidungen und Implementierung die Vor- und Nachteile einzelner Programmiersprachen. Genau diese Design und Implementierung wird in der Regel angegangen, wenn Softwareprodukte größere Verbreitung finden.

Selbst beim Microcontroller ist es weit wichtiger, dass man seinen Code derart gestaltet, dass die µC und Peripherie in Tiefschlaf verfallen kann und auf Trigger wartet, anstatt sinnlos Leerzüglen zu verballern.
 
  • Gefällt mir
Reaktionen: BeBur
Piktogramm schrieb:
Och die Diskussion über langsame Programmiersprachen und langsamen Code ist soooo alt. Ganz realistisch überwiegen Designentscheidungen und Implementierung die Vor- und Nachteile einzelner Programmiersprachen. Genau diese Design und Implementierung wird in der Regel angegangen, wenn Softwareprodukte größere Verbreitung finden.

Das stimmt und dennoch ist sie nicht beantwortet worden in dieser Hinsicht.
Und gerade, dass diese Kriterien überwiegen, obwohl bei richtiger Umsetzung des Compilers das gar nichts damit zu tun hat, ist ein Problem.
Es gibt auch keine hinreichenden Studien/Untersuchungen, die entsprechendes überhaupt erfassen.

Piktogramm schrieb:
Selbst beim Microcontroller ist es weit wichtiger, dass man seinen Code derart gestaltet, dass die µC und Peripherie in Tiefschlaf verfallen kann und auf Trigger wartet, anstatt sinnlos Leerzüglen zu verballern.

Das stimmt nicht ganz.
Zunächst einmal hast du recht. Es ist sinnvoll Komponenten in den Tiefschlaf zu versetzen. Bei einem AT(Tiny) entsprechender Ausstattung reden wir hier von 2µA Verbrauch.
Damit wird aber umso wichtiger, wie lange Controller und Peripherie überhaupt wach sind. Denn das macht fast den kompletten Stromverbrauch aus (nach Modell, Spannung und Taktrate und Taktgeber 2-20mA), während der Verbrauch im Tiefschlaf innerhalb der Selbstentladung des Energiespeichers liegt.
Wenn der Controller hier, um bei Python zu bleiben, 300mal länger braucht als sonst, habe ich ein Problem, weil ebenso viel ist der Stromverbrauch gewachsen.
Die Diskussion gibt es in ähnlichen Zügen bei der Frage, ob es stromsparender ist, den Mikrocontroller hochgetaktet zu lassen, oder ihn runtergetaktet laufen zu lassen.
 
Wasserhuhn schrieb:
Das stimmt und dennoch ist sie nicht beantwortet worden in dieser Hinsicht.
Und gerade, dass diese Kriterien überwiegen, obwohl bei richtiger Umsetzung des Compilers das gar nichts damit zu tun hat, ist ein Problem.
Sprachliches Kleinklein:

In welcher Hinsicht genau? Das Feld der Optimierung und Analyse von Programmiersprachen, Laufzeitumgebungen, Compilern, Performance und damit verbundener Energieeffizient ist nahezu beliebig komplex.
Genauso, welche Kriterien? Das Demonstrativpronomen "diese" sollte auf irgend ein Subjekt/Objekt im Kontext verweisen. Kriterien führst aber weder du, noch ich im von dir zitiertem Teil an.
Was der Nebensatz mit dem Compiler soll ist für mich gar nicht verständlich, womit hat der Compiler nichts zu tun?

Genauer zu schreiben, worauf man hinaus will, hilft allen Anderen beim Verstehen ;)


#############################################################

Studien an der Stelle sind auch vergleichsweise sinnlos. Der Erkenntnisgewinn wäre vergleichsweise klein zu dem was man im Alltag sowieso tut um Programme zu optimieren. Beim Profiling von Programmen bzw. dessen Bestandteilen fällt unheimlich viel Information darüber an, wo ein Programm bzw. dessen Bestandteile sich wie verhalten, woraus sich auch Energieeffizienz ableiten lässt.

Wasserhuhn schrieb:
Wenn der Controller hier, um bei Python zu bleiben, 300mal länger braucht als sonst, habe ich ein Problem, weil ebenso viel ist der Stromverbrauch gewachsen.
Python ist wirklich massiv viel langsamer wenn es um Numbercrunching geht. Deswegen wäre es auch eine pfuschige Designentscheidung da kein numpy zu nutzen. Numpy selbst nutzt im Hintergrund BLAS und Lapack und diese oder vergleichbare Bibliotheken würde man auch unter C nutzen. Die Cluelogic die man dann selber schreibt sollte von der Laufzeit egal ob Python oder C <1% der Laufzeit ausmachen. Da lohnt Optimierung irgendwann nicht mehr.
Bei µControllern und Anwendungen, bei denen Akkulaufzeit wichtig ist, ist meist nicht das Problem, dass man auf irgendwas lange rechnen muss. Schaut man sich das mal an, bringen viele µController viel Zeit damit zu, dass sie auf das Einschwingen ihre Sensoren und Funkmodems warten, nachdem sie aus dem Tiefschlaf kommen. Beim Warten ist es fast egal welche Sprache da zum Einsatz kommt. Wer helle ist, versucht diese Einschwingphasen aller Peripherie nebenläufig hinzubekommen. Allein solche Optimierungen sind in der Regel mehr wert, als C oder µPython auf einem µC.
Wer hingegen Numbercrunching auf einem µC betreibt, der Energie sparen soll, hat ein ganz anderes Problem. Für sowas gibt es µCs mit entsprechenden Funktionsblöcken (Crypto, Hashing) oder PLAs oder FPGAs.

Wasserhuhn schrieb:
Die Diskussion gibt es in ähnlichen Zügen bei der Frage, ob es stromsparender ist, den Mikrocontroller hochgetaktet zu lassen, oder ihn runtergetaktet laufen zu lassen.
Profiling und Messgeräte können sowas im konkreten Fall beantworten. Realistisch aber nicht im allgemeinen Fall.
 
  • Gefällt mir
Reaktionen: TomH22
Piktogramm schrieb:
In welcher Hinsicht genau?
Gesamter Stromverbrauch und Effizienz. Nichts weiter. Das sollte eigentlich klar sein.
Piktogramm schrieb:
Genauso, welche Kriterien?
"Features" gewisser Sprachen und Frameworks, alles, was eine vermeintlich geringere Entwicklungszeit bedeuten möchte.
Piktogramm schrieb:
Was der Nebensatz mit dem Compiler soll ist für mich gar nicht verständlich, womit hat der Compiler nichts zu tun?
Weil der Code noch so toll und woke aussehen kann, das aber egal ist, wenn der Compiler das übersetzt hat. Daher sind die Kriterien, die du genannt hattest, völlig irrelevant. Der JIT-Interpreter ist im Falle Python das Problem.
Piktogramm schrieb:
Studien an der Stelle sind auch vergleichsweise sinnlos. Der Erkenntnisgewinn wäre vergleichsweise klein zu dem was man im Alltag sowieso tut um Programme zu optimieren.
Es ist wissenschaftlich fundiert eine These zu verfassen. Hinzugehen und das nicht zu überprüfen eher nicht.
Piktogramm schrieb:
Beim Profiling von Programmen bzw. dessen Bestandteilen fällt unheimlich viel Information darüber an, wo ein Programm bzw. dessen Bestandteile sich wie verhalten, woraus sich auch Energieeffizienz ableiten lässt.
Das stimmt und ist auch schön. Ersetzt aber nicht das was ich mir wünsche. Ich würde gerne wissen, wie aktuell in Bereichen gestaffelt (auf Servern, auf Privatsystemen) welcher Code wie läuft und wie viel Strom er verbraucht.
Piktogramm schrieb:
Bei µControllern und Anwendungen, bei denen Akkulaufzeit wichtig ist, ist meist nicht das Problem, dass man auf irgendwas lange rechnen muss. Schaut man sich das mal an, bringen viele µController viel Zeit damit zu, dass sie auf das Einschwingen ihre Sensoren und Funkmodems warten, nachdem sie aus dem Tiefschlaf kommen.
Das ist mir zu pauschal und deckt sich nicht mit meinen Erfahrungen.

Und wenn ich einen Interpreten auf meinem Controller laufen lasse, ist mir die (Akku)Laufzeit eh nicht wichtig, oder dadurch, dass das Teil schon Micropython unterstützt, ist er so mächtig, dass eher sehr hungrige Peripherie vorhanden ist (, die den starken Controller rechtfertigt), die der Flaschenhals ist.

Den AT(Tiny) nannte ich nicht umsonst, meine Welt sind keine STMs mit X Kernen, sondern sehr spärliche Controller und Geräte, die ein paar Monate bis Jahre mit einer Akkuladung laufen sollen.

Meine Vermutung ist, dass die Gesamtheit aller Systeme signifikant Strom verschwendet, weil Code von langsamen JIT-Interpreten verarbeitet wird.
Studien finde ich dazu keine.
Dagegen spricht, dass Unternehmen gerne effizient ihre Services anbieten möchten und entsprechend Serverkosten senken möchten.
Dafür spricht meine Erfahrung, dass Leute gerne mal eine halbe Stunde auf ihr langsames Python-Skript warten, anstatt es richtig zu machen. Am besten noch Forschung mit klassifizierten Informationen, was alles in der Cloud in den USA berechnet wird. Meine Erfahrung, leider schon gesehen.
 
Wasserhuhn schrieb:
Weil der Code noch so toll und woke aussehen kann
Sorry, für das offtopic, aber „Woke“ kann Code nicht aussehen. Das eine hat mit dem anderen absolut gar nichts zu tun. Das ist schlicht nicht möglich. Ich möchte dir in der Sache nicht widersprechen, aber du tust dir mit solchen schnellschuss Adjektiven aus der Hüfte argumentativ keinen Gefallen.
 
  • Gefällt mir
Reaktionen: BeBur und Piktogramm
Wasserhuhn schrieb:
Abseits von anderen Problemen die Python hat, in der heutigen Zeit mal die gesellschaftliche Frage, ob man, wenn man Glühbirnen mit 10%(?) Lichtausbeute verbietet, man nicht Python und co. verbieten sollte bzw. deren JIT-Interpreter.
"Nicht alles was hinkt ist ein Vergleich" ;)

Ein komplexes IT System mit einer Glühbirne zu vergleichen ist wenig zielführend.
Die Glühbirne hat tatsächlich nur eine gewünschte Funktion, und das ist Licht zu erzeugen.

Es ist auch wenig sinnvoll sich einen einzigen isolierten Teilaspekt, in Deinem Fall Python Code, herauszugreifen. Also die Idee Python analog zu Glühbirnen zu verbieten, ist schon eine witzige Idee.

Es funktioniert auch nicht, Effizienzbetrachtungen von einen ATTiny auf Enterprise IT zu übertragen.

Der ATTiny hat ein paar KB fixen Code in seinem Flash-Speicher, üblicherweise kein Betriebssystem oder anderen Overhead. D.h. 100% der Ausführungszeit ist Anwendungscode.

Schon bei irgendeinem "Smart Home" Gerät wie einem steuerbarem LED Leuchtmittel, geht geschätzt 99% der Energie für die Kommunikation drauf (Baseband Layer, Netzwerkprotokoll, Verschlüsselung, usw.). Der Code, der hinterher mit ein paar Zugriffen auf I/O Register die Farbe/Helligkeit der Leuchte einstellt, fällt nicht mehr ins Gewicht.

Und das gilt für "große" Systeme in der Cloud oder RZ sinngemäß genauso. Wenn ich mir die Auslastung der VMs bei uns im Unternehmen so ansehe, dann sind die meisten den größten Teil der Zeit nicht besonders hoch ausgelastet. Deswegen macht ja aggressives Power Management, was zunächst ja für Mobilgeräte entwickelt wurde, auch im Serverbereich absolut Sinn. Also Kerne oder ganze Teile der Prozessoren (wie Cache) abzuschalten (bzw. durch Clock-Gating "einzufrieren") und den Takt dynamisch anpassen. Das wird in Summe sehr viel mehr bringen, als zu versuchen den Anwendungscode "energetisch" zu optimieren.

Der andere Punkt wo Deine Argumentation zu kurz greift, ist dass Du nur den direkten Energieverbrauch der Code Ausführung betrachtest.
Die Entwicklung des Codes kostet auch Energie. Dein PC hat während der Entwicklung der ATTiny Anwendung ein vielfaches an Strom verbraucht, im Vergleich was Deine MCU selbst bei einer sehr langen Einsatzdauer jemals verbrauchen wird. Jetzt ist nun die typische Anwendung auf einem ATTiny ein paar hundert Zeilen C Code, und hier ist C auch der richtige Abstraktionslevel, sprich mit Python hättest Du vermutlich keine kürzere Entwicklungszeit.

Für viele andere Anwendungen gilt das aber nicht, hier kann man mit dem Einsatz von Programmiersprachen mit höherem Abstraktionslevel sehr viel Entwicklungszeit einsparen. Das macht man natürlich hauptsächlich aus anderen Gründen (Kosteneinsparung, Time-To-Market, Verfügbarkeit von Entwicklern mit entsprechenden Skills) , aber es hat eben auch Seiteneffekte auf den gesamten Energieverbrauch des Unternehmens.

Natürlich wird es von der jeweiligen Situation abhängen, welche Effekte überwiegen.

Wasserhuhn schrieb:
Dafür spricht meine Erfahrung, dass Leute gerne mal eine halbe Stunde auf ihr langsames Python-Skript warten, anstatt es richtig zu machen.
Das kommt eben darauf an, wie häufig man dieses Python-Skript braucht. Außerdem stellt sich die Frage ob die halbe Stunde dann wirklich 30 CPU Minuten Python Code sind, oder Code einer in C-geschriebenen Library, oder gar warten auf I/O.

Python Code wird häufig für "Glue-Logik" eingesetzt, der Daten aus verschiedenen Quellen anfordert, integriert, umformt und dann irgendwo hinschreibt oder an z.B. ML-Modelle übergibt.

Daten liegen heute meist in irgendwelchen Text-Formaten vor (XML, json, YAML, usw.), Kommunikation findet über textorientierte Schnittstellen wie HTTP/REST statt. D.h. man hat dabei einen hohen Anteil an Parsing/Pattern-Matching, Slicing, usw.

Dafür eignen sich Sprachen wie Python sehr gut, der größte Teil der CPU-Zyklen wird dann sowieso in der Laufzeitumgebung verbraucht, die dann hoffentlich halbwegs effizienter "native"-Code ist.
 
Zuletzt bearbeitet:
TomH22 schrieb:
Für viele andere Anwendungen gilt das aber nicht, hier kann man mit dem Einsatz von Programmiersprachen mit höherem Abstraktionslevel sehr viel Entwicklungszeit einsparen
Z.B. Rust fiele hier drunter, hätte aber dennoch eine Effizienz auf dem Niveau von C.

Im Vergleich zu Python, muss man sich zwar mit static typing einschlagen, wo man sich aber auch fragen muss, ob es langfristig nicht sogar einen Vorteil gibt


Insgesamt wäre es doch Mal interessant ein Beispielprojekt zu haben, wo man die Unterschiede sehen kann.

Geringerer Energieverbrauch wiegt aber bei den kleinen Verbrauchern am Konsumenten am meisten:
Einerseits werden davon tausende bis Millionen produziert.
Andererseits redet man sobald Batterien und Akkus ins Spiel kommen von ganz anderen Aufwänden wie z.B. dem häufigeren Wechsel und der Produktion von mehr Akkus und Batterien, oder der plötzlich deutlich erschweren Möglichkeit komplett ohne externe Stromquelle auszukommen (energy harvesting durch kleine PV, Wärme, etc.)
 
Zuletzt bearbeitet:
KitKat::new() schrieb:
Z.B. Rust fiele hier drunter, hätte aber dennoch eine Effizienz auf dem Niveau von C.
Ich muss zugeben, dass ich Rust bisher nur recht "oberflächlich" angesehen habe.

Ein zentrales Argument bei Rust sind ja "Zero-Cost" Abtractions, also darum, das die Abstraktionen keine zusätzliche Laufzeit kosten. Da nun mal die Fähigkeiten der Hardware fix sind, bedeutet das, dass es in erster Linie darum geht, Low-Level Code in sichererer Form als in C zu schreiben.

Ich glaube auch das von Sprachen wie Rust nur Entwickler profitieren, die eine solide Ausbildung in theoretischen Konzepten der Informatik haben.

Was häufig verkannt wird, ist das sehr große Mengen an Code von Leuten geschrieben werden, die eigentlich Quereinsteiger sind, und durch den allgemeine Dominanz von IT in allen Lebensbereichen zum Programmiergen gekommen sind. Ob das z.B. Leute mit betriebswirtschaftlichen Background (z.b. im ganzen SAP/ABAP Bereich), Medien/Grafik/Design (Webentwicklung), oder z.B. Mathematik (im Bereich Data Science) sind, ist egal. Die haben häufig extrem gutes Domänenwissen, verstehen auch ihre Algorithmen sehr gut, aber haben eben Schwächen bei den theoretischen Grundlagen der Informatik. Wir haben bei uns im Unternehmen eine Date Science Abteilung, die schreiben auch viel Code in Python und R oder nutzen Tools wie Spotfire oder PowerBI. Die sagen auch von sich selbst, das sie in erster Lineie "Data Scientists" sind und keine Software Entwickler.

Der Übergang vom Anwender zum Entwickler ist im IT Bereich fließend. Letztendlich sind auch Excel Macros die von Controllern geschrieben werden, Code.


KitKat::new() schrieb:
Im Vergleich zu Python, muss man sich zwar mit static typing einschlagen, wo man sich aber auch fragen muss, ob es langfristig nicht sogar einen Vorteil gibt
Ich habe den 30 Jahren die ich programmiere, schon in so ziemlich mit jedem Sprach-Paradigma zu tun gehabt und auch schon auf sehr vielen Ebenen programmiert. Ich würde aus meiner Erfahrung nicht sagen, das statisch typisierte vs. dynamisch typisierte Sprachen eindeutige Vor-oder Nachteile haben.
Das Argument ist ja, das statisch typisierten Sprachen Dinge schon zur Compile-Zeit prüfen, die bei dynamisch typisierten Sprachen erst zur Laufzeit auffallen.
Das das generell stabileren Code ergibt, deckt sich nicht mit meiner Lebenserfahrung. "Klassische" statisch-typisierte Sprachen wie C haben dafür überhaupt keine Typinformationen und Prüfungen mehr zur Laufzeit, das führt dann dazu, das ein ungültiger Typcast zu Memory Corruption und/oder Crash führt. Das sind ja auch bekanntermaßen die großen Einfallstore für Exploits.

Und gerade wenn ich sowieso relativ lose gekoppelte Systeme habe, die über Formate wie XML oder JSON kommunizieren, haben die dynamischen Sprache einfach große Vorteile bezüglich der Produktivität.
 
TomH22 schrieb:
Da nun mal die Fähigkeiten der Hardware fix sind, bedeutet das, dass es in erster Linie darum geht, Low-Level Code in sichererer Form als in C zu schreiben.
Nein, es geht darum speicher-und Concurrency-sichere Abstraktionen zu haben, kein manuelles Memory Management betreiben zu müssen, wo es nicht prinzipiell notwendig ist, und trotzdem effizient zu sein.

Ich glaube auch das von Sprachen wie Rust nur Entwickler profitieren, die eine solide Ausbildung in theoretischen Konzepten der Informatik haben.
Ich glaube eher, dass uns glauben über etwas was man nicht kennt überhaupt nicht weiterhilft.
Rust benötigt bei der programmierung nicht mehr konzeptuellen Wissen als C++. Niemand erwartet TI-Kenntnisse beim Programmieren mit C++.


TomH22 schrieb:
Das das generell stabileren Code ergibt, deckt sich nicht mit meiner Lebenserfahrung.
Mit meiner schon.
Und mit der anderer auch.
Nicht umsonst ist TypeScript so beliebt, das ja nichts anderes macht als statische Typisierung zu JS hinzuzufügen (was ja auch durchaus mit Aufwand verbunden ist), oder Python Type Annotations hinzufügt ;)


TomH22 schrieb:
"Klassische" statisch-typisierte Sprachen wie C haben dafür überhaupt keine Typinformationen und Prüfungen mehr zur Laufzeit, das führt dann dazu, das ein ungültiger Typcast zu Memory Corruption und/oder Crash führt. Das sind ja auch bekanntermaßen die großen Einfallstore für Exploits.
Das sind eher klassische hardwarenahe Programmiersprachen. Typisierung hat damit nichts zu tun, sh. Java, welches sogar Reflection kann und trotzdem typisiert ist.

TomH22 schrieb:
Und gerade wenn ich sowieso relativ lose gekoppelte Systeme habe, die über Formate wie XML oder JSON kommunizieren, haben die dynamischen Sprache einfach große Vorteile bezüglich der Produktivität.
Warum?
 
Wasserhuhn schrieb:
Gesamter Stromverbrauch und Effizienz. Nichts weiter. Das sollte eigentlich klar sein.
Ne allein Energieverbrauch und Effizienz sind zwei unterschiedliche Paar Schuhe. Den Energieverbrauch kann man am besten dadurch senken, dass man nichts tut. Erst die Effizienz bedingt, dass man ein zu maximierenden Output (Rechenergebnis/Steuerung) hat und ein zu minimierenden (aber nicht zu eliminieren!) Input (Energie).
Das Herangehen unterscheidet sich ja nach konkretem Fall gar nicht oder extrem. Deswegen ist es eben nicht "klar".

Zudem können sich beide Ziele im Konflikt stehen. Die Effizienz kann man erhöhen, indem man den Output bei selben Input erhöht. Damit senkt man kosten, was zu erhöhter Nachfrage/Nutzung führen kann. Wenn der Anstieg der Nutzung dabei stärker wird, als der Effizienzgewinn, steigt absolut der Energieverbrauch.

Wasserhuhn schrieb:
"Features" gewisser Sprachen und Frameworks, alles, was eine vermeintlich geringere Entwicklungszeit bedeuten möchte.
Die Frage nach Kritierien mit "Features" zu beantworten ist merkwürdig. Da hast du mich verloren.

Wasserhuhn schrieb:
Weil der Code noch so toll und woke aussehen kann, das aber egal ist, wenn der Compiler das übersetzt hat. Daher sind die Kriterien, die du genannt hattest, völlig irrelevant. Der JIT-Interpreter ist im Falle Python das Problem.
Was soll bitte "woke" an der Stelle? Woke als "wir habens verstanden und sind toll" kenne ich und "woke" als rechtes Dogwhistling, aber im Kontext von Programmiersprachen und IT-Systemen wird es komisch und wirkt wie wildes uUherwerfen von Wörtern.
JIT-Compiler sind in der Regel auch kein all zu großes Problem, zudem man Python auch als Bytecode ausliefern kann und die Interpreterphase damit vermeidet.

Wasserhuhn schrieb:
Es ist wissenschaftlich fundiert eine These zu verfassen. Hinzugehen und das nicht zu überprüfen eher nicht.
Wissenschaftliches Arbeiten ist das Eine, darauf Studien zu machen ist das Andere. Das was du willst, dass sich jemand mit einem Profiler an Programmcode und Gerät/Microcontroller hängt um die Effizienz eines Systems zu optimieren ist einfach Alltag. Dabei kommt wissenschaftliche Methodik zum Einsatz, es ist nur so banal, dass die Veröffentlichung nicht taugt.
Bei einigen Funkmodems ist es sogar üblich, dass man Messreihen bzw. Diagramme zur Leistungsaufnahme in verschiedenen Betriebsmodi und beim Wechsel zwischen diesen im Datenblatt bekommt.

Wasserhuhn schrieb:
Das stimmt und ist auch schön. Ersetzt aber nicht das was ich mir wünsche. Ich würde gerne wissen, wie aktuell in Bereichen gestaffelt (auf Servern, auf Privatsystemen) welcher Code wie läuft und wie viel Strom er verbraucht.
Bei einem Server mit zig aktiver aktiven Komponenten & Peripherie und zig Softwarekomponenten ist das ein N-Dimensionales mit N als Anzahl jeder Komponente. Also extrem aufwendig. Vernünftige Menschen werden eine ABC-Analyse oder vergleichbares machen und allenfalls die 20% der Komponenten untersuchen, die ernsthaft Ressourcen (meist Rechenzeit und I/O) belegen. Also Strommessgerät ans System, kritische Komponente unter definierte Lastzustände setzen und mit einem Profiler kritische Pfade optimieren.
Viel genauer wird es auch nicht, wenn man sich nicht selbst in die Tasche lügen will.

Wasserhuhn schrieb:
Meine Vermutung ist, dass die Gesamtheit aller Systeme signifikant Strom verschwendet, weil Code von langsamen JIT-Interpreten verarbeitet wird.
Ganz sicher läuft viel Anwendungen, die man noch extrem optimieren könnte. Anderseits läuft sehr viel Kram dadurch automatisiert, sodass die Effizienzgewinne im vergleich zu manueller oder analoger Steuersysteme im Vergleich bereits enorm gewachsen ist.

Wasserhuhn schrieb:
Dafür spricht meine Erfahrung, dass Leute gerne mal eine halbe Stunde auf ihr langsames Python-Skript warten, anstatt es richtig zu machen. Am besten noch Forschung mit klassifizierten Informationen, was alles in der Cloud in den USA berechnet wird. Meine Erfahrung, leider schon gesehen.
Was Forscher/Studenten außerhalb und teils innerhalb der IT verbrechen ist das Eine. Anderseits wird bereits die Pythonanwendung schneller, zuverlässiger und im Endeffekt mit weniger Energieaufwand Daten umsetzen als es semi manuell mit Excell erfolgen würde.


Edit:
Und kann es sein, dass du alles sehr aus deiner ATTiny-Welt heraus siehst? So ein ATTiny ist ja wirklich ein Kleinstsystem, bei dem man alle Komponenten verstehen kann und umfangreiche Optimierung im Vergleich wirklich simpel ist. Es scheint etwas am Verständnis zu mangeln, dass diese Form der Optimierung einige Gewichtsklassen weiter oben nahezu unmöglich wird.
 
Zuletzt bearbeitet:
How pathetic can you get?

Und das war so eine nette Diskussion um Codemodellierung. Da lieber dem Ansatz des @TE folgen und sagen "eine Zeile weniger ist besser als eine mehr" als sich in irgendwelche Debatten von "aber Blubbs ist besser als Facks, einsdrölf" zu verrennen.

Schlechter Code läuft überall schlecht. Gut verständlicher Code ist überall verständlich. Die Auswahl des Interpreters oder des Compilers hat damit nicht das geringste zu tun, und wenn sich paar Foristen auf den Kopf stellen und mit den Arschbacken La Paloma pfeifen (sorry, Stefan).
 
  • Gefällt mir
Reaktionen: Quonux und Grimba
KitKat::new() schrieb:
Nein, es geht darum speicher-und Concurrency-sichere Abstraktionen zu haben, kein manuelles Memory Management betreiben zu müssen, wo es nicht prinzipiell notwendig ist, und trotzdem effizient zu sein.
Das meinte ich mit "sicherer Low-Level Code". Memory Management inkl. Lebensdauer von Objekten ist für mich eine "Low-Level" Funktion die immer benötigt werden. Das ist auch ganz klar die große Schwäche von C, der Programmierer ist komplett allein dafür verantwortlich, wenn er z.B. einen Zeiger auf eine lokale Variable über die Lebensdauer des jeweiligen Stackframes hinaus verwendet. D.h. in diesem Fall bietet Rust bessere Abstraktionen für diese Basisfunktionen. Und die kosten auch keine Laufzeit, weil sie überwiegend statisch zur Compiler Zeit gelöst werden.

Sprachen wie Python setzt man aber wegen der "höheren" Abstraktionen, wie Listen, Tupel, Dictionary und entsprechenden Operationen darauf ein.
Rust bietet natürlich, genau wie C++ entsprechende Funktionen in der Standard-Library an. Ob nun ein Python Programm das unter Verwendung dieser Abstraktionen nach Rust portiert wird, jetzt dann viel schneller läuft als der ursprüngliche Python Code, hängt nun sehr davon ab, wie gut es geschrieben ist.
Wenn da jemand 1000 mal linear durch eine Liste mit einer Million Elementen sucht dann wird aus dem lahmen Python Programm ein lahmes Rust-Programm ;)

KitKat::new() schrieb:
Rust benötigt bei der programmierung nicht mehr konzeptuellen Wissen als C++. Niemand erwartet TI-Kenntnisse beim Programmieren mit C++.
Vielleicht war "theoretische Konzepte" etwas hoch gegriffen. Rust sieht sich ja als Alternative zu C und zu C++. Und ich stelle mir so den typischen Embedded-C Programmierer, der in "Bits und Bytes" denkt vor wenn er mit Traits oder Pattern-Matching konfrontiert wird.

KitKat::new() schrieb:
Und mit der anderer auch.
Kannst Du "anderer" näher spezifizieren?
KitKat::new() schrieb:
Nicht umsonst ist TypeScript so beliebt, das ja nichts anderes macht als statische Typisierung zu JS hinzuzufügen (was ja auch durchaus mit Aufwand verbunden ist), oder Python Type Annotations hinzufügt ;)
Als ich das erste mal Typescript gesehen habe, war ich zunächst auch sehr begeistert davon und habe auch ein Node.js Projekt, an dem ich gerade am arbeiten war, darauf umgestellt. Im Laufe der Zeit kam dann doch etwas Ernüchterung auf, insbesondere wenn man 3th Party Libraries verwendet. Nicht immer gibt es passende Typings. Meist sind die Typings komplett undokumentiert und der Beispielcode der Library ist plain-Javascript. Speziell wenn viel mit Generics gearbeitet wird, ist es nicht immer sofort eingängig, wie das Typing zu benutzen ist. Man merkt dann allerdings auch schnell, ob der entsprechende Javascript Code halbwegs sinnvoll konzipiert ist, oder ein wildes Chaos darstellt, der z.B. ständig komplett unterschiedlich aufgebaute Objekte zurückgibt.

Das ist jetzt zugegebenermaßen auch schon wieder ein paar Jahre her, ich habe da schon länger nichts mehr gemacht und auch die Weiterentwicklung von Typescript nicht mehr verfolgt. Am Ende stellt sich halt immer die Frage nach dem "Nettonutzen". Sprich ob die zusätzlich aufgewendete Zeit für Typescript sich am Ende auszahlt.


KitKat::new() schrieb:
Das sind eher klassische hardwarenahe Programmiersprachen. Typisierung hat damit nichts zu tun, sh. Java, welches sogar Reflection kann und trotzdem typisiert ist.
Ich habe ja geschrieben "klassische ... Sprachen wie C" insofern meinen wir das Gleiche. Hat Rust Reflektion?

KitKat::new() schrieb:
Nun, ich hatte da speziell Javascript/node.js in Zusammenhang mit REST Schnittstellen als Beispiel im Kopf:
Ich kann ja direkt zwischen dem json-Text und javascript Objekten konvertieren und greife dann im meinem Code direkt auf die Objekte zu. Natürlich kann ich dass auch z.B. in C oder C++ so machen und nutze einfach eine entsprechende json Library.

Alternative kann die entsprechenden Strukturen im Typsystem meiner Sprache spiegeln und dann entsprechenden Code zum einlesen/sichern dieser Strukturen bauen. Wenn ich ein hinreichend komplexe Logik implementieren muss, ist das auch der richtige Weg. Aber es gibt eben auch Anwendungsfälle wo dieser Overhead nicht notwendig ist.

RalphS schrieb:
Schlechter Code läuft überall schlecht. Gut verständlicher Code ist überall verständlich. Die Auswahl des Interpreters oder des Compilers hat damit nicht das geringste zu tun, und wenn sich paar Foristen auf den Kopf stellen und mit den Arschbacken La Paloma pfeifen (sorry, Stefan).
Dem stimme ich zu 100% zu. Das ist für mich auch das Problem an der, gerade in den letzten Jahren zu beobachtenden "Inflation" der Programmiersprachen. Es gibt anscheinend ein Bedürfnis danach, aber auf mich wirkt es immer wie die Suche nach dem heiligen Gral.

Ob sich damit die fundamentalen Probleme der Softwareentwicklung lösen lassen, ich glaube kaum. Weil in den seltensten Fällen die Programmiersprache der Grund für die Probleme ist.
 
Zuletzt bearbeitet:
TomH22 schrieb:
Das meinte ich mit "sicherer Low-Level Code". Memory Management inkl. Lebensdauer von Objekten ist für mich eine "Low-Level" Funktion die immer benötigt werden.
Es ist aber nicht sicherer Low-Level-Code. Es ist sicherer High-Level Code, weil "unsicherer" Low-Level Code wegabstrahiert werden kann, und manuelles Speichermanagement muss man in Rust eben nicht machen.

TomH22 schrieb:
Sprachen wie Python setzt man aber wegen der "höheren" Abstraktionen, wie Listen, Tupel, Dictionary und entsprechenden Operationen darauf ein.
Wie das, wenn man das doch auch in Rust und C++ hat?

Warum ich Python nutze?
Das Machine Learning Ökosystem ist hauptsächlich Python.
Mit Python kann man schnell Sachen zusammenstöpseln.
Ich nutze von irgendjemanden ein Script und das ist zufällig in Python geschrieben.

Nicht: Es gibt Listen, Tupels und Dictionaries, das hat man fast überall

TomH22 schrieb:
Ob nun ein Python Programm das unter Verwendung dieser Abstraktionen nach Rust portiert wird, jetzt dann viel schneller läuft als der ursprüngliche Python Code, hängt nun sehr davon ab, wie gut es geschrieben ist.
Wenn da jemand 1000 mal linear durch eine Liste mit einer Million Elementen sucht dann wird aus dem lahmen Python Programm ein lahmes Rust-Programm ;)
War selbst überrascht:
Der Unterschied ist etwa Faktor 70-80 (zahlen kleiner 10 zählen, alles single threaded, obwohl gerade Rust sehr leichtes multithreading erlauben würde).

TomH22 schrieb:
Ich habe ja geschrieben "klassische ... Sprachen wie C" insofern meinen wir das Gleiche. Hat Rust Reflektion?
klassische statisch-typisierte Sprachen hast du geschrieben, und dich auch auf Typisierung bezogen, aber Details herausgegriffen, die nichts mit Typisierung zu tun haben... nein Rust hat atm keine Reflektion.

TomH22 schrieb:
Am Ende stellt sich halt immer die Frage nach dem "Nettonutzen". Sprich ob die zusätzlich aufgewendete Zeit für Typescript sich am Ende auszahlt.
ich kenne kein Projekt, das von TypeScript wieder auf JS zurück ist, oder in Python die Annotations wieder weglässt.
Hier scheint zu gelten: mehr Code = besser
 
  • Gefällt mir
Reaktionen: BeBur
TomH22 schrieb:
die in der Regel wenig konsistent sind,
Sag doch gleich dass das meiste redudant ist und ein 3 Mal kleineres Programm das gleiche könnte.
Ergänzung ()

RalphS schrieb:
Abstraktionen sind nochmal ein eigenes Thema. Die blasen den Code ebenfalls auf, wie ja schon erwähnt wurde, aber machen ihn eben auch wiederverwendbar(er).
Bei OOP meistens in der Theorie aber nicht in der Praxis. Falls sich die Schnittstelle (ich meine nicht nur eine Klasse sondern in der Software Architektur) ändert muss man sowieso meistens zu viel umbauen oder neu schreiben.
Bei Funktionalen Sprachen geht das etwas besser.
 
Zuletzt bearbeitet:
Quonux schrieb:
Falls sich die Schnittstelle (ich meine nicht nur eine Klasse sondern in der Software Architektur) ändert muss man sowieso meistens zu viel umbauen oder neu schreiben.
Dann macht man entweder was falsch oder sollte sich Interfaces mal angucken. Klar, manchmal ist Neubau unumgänglich, aber das ist dann doch eher selten(er).
 
Zurück
Oben