Theo
Hallo und herzlich willkommen moin moin zu einer neuen Ausgabe des Sandpapiers, unserem Sandstorm Weekly Podcast, bei dem wir über Themen, Herausforderungen und Experimente aus unserem Unternehmensalltag sprechen. Heute habe ich zwei sehr spannende Gäste bei mir, das ist zum einen der Sebastian Kurfürst. Hi Sebastian.
Sebastian
Hallihallo.
Theo
Und der Martin Penkert. Hi Martin.
Martin
Hallo, ich freue mich darauf mal Gast zu sein.
Theo
Ich freue mich auch, dich als Gast dabei zu haben. Und zwar soll es heute ein etwas technischeres Thema werden. Es soll um premature abstraction und premature optimization, also verfrühte Abstraktion und verfrühte Optimierung in Quellcode gehen. Hintergrund ist, dass ich ganz oft mit anderen Entwicklerinnen und Entwicklern spreche, die aus meiner Sicht mit oft guter Intention ihren Code tendenziell etwas schlechter wahrtbar machen, nach meiner persönlichen Auffassung. Und deswegen wollen wir einfach mal erörtern, ist das überhaupt so, vielleicht ist meine Wahrnehmung auch falsch und wie kann man denn vorgehen, wenn man so etwas feststellt? Da das eine technischere Folge wird, können wir natürlich wahrscheinlich nicht jedes einzelne Detail perfekt erläutern. Wir werden auf jeden Fall aber versuchen, dass auch Nicht-Entwicklerinnen und Nicht-Entwickler die Grundprinzipien einigermaßen nachvollziehen können, sodass es vielleicht auch für Leute, die eher im Projektmanagement unterwegs sind, funktionieren kann. Wir geben uns auf jeden Fall Mühe. Gut, steigen wir also ein. Meine allererste Frage beim Thema verfrühte Abstraktion, Sebastian, was ist denn aus deiner Sicht überhaupt in der Softwareentwicklung eine Abstraktion?
Sebastian
Ja, es ist tatsächlich nicht so einfach zu beantworten. Ich glaube, wir sollten noch mal ganz kurz sagen, weshalb, also eigentlich ist es sozusagen eine Schicht, in der Regel eine Schicht, eine Kiste, um irgendwas mit dem Ziel, Funktionalität wiederverwendbar zu machen. Also ich habe ja quasi, also viele Themen, viele Probleme ähneln sich halt und deshalb ist das die Idee, man versucht den gleichen Anteil von zwei Problemen zum Beispiel rauszuziehen, ich sag mal, in eine Funktion, in eine Kiste zu stecken und den dann aus verschiedenen anderen Teilen wiederzuverwenden und die Hoffnung ist dabei halt, dass man damit ja den Code oder das Programm halt besser pflegbar, besser wartbar und so weiter macht. Ja, also im Prinzip das Packen von Kisten letztendlich, würde ich sagen, ist Abstraktion.
Theo
Martin, würdest du dem zustimmen oder würdest du dem was hinzufügen wollen?
Martin
Also zu der Definition von Abstraktion würde ich da erst mal zustimmen.
Theo
Okay, also dieses Packen, das klingt ja für mich jetzt grundsätzlich eigentlich erstmal ganz praktisch. Ich hab dann offensichtlich irgendwas, was ich scheinbar leichter benutzen kann. Warum kann es denn, Martin vielleicht gehst du mal drauf ein, warum kann es denn gegebenenfalls ungünstig sein, zu früh eine solche Abstraktion zu bauen?
Martin
Das ist eine ziemlich weite Frage. Ich denke, das Problem mit Abstraktion ist immer, dass du quasi das Level verlässt, auf dem du dich gerade bewegst und versuchst, quasi auf ein höheres Niveau zu kommen, um etwas zu erschaffen, das wiederverwendbar ist in der Zukunft. Und wenn du das zu früh machst, dann machst du das vielleicht zu einem Zeitpunkt, an dem du die Zukunft noch gar nicht kennst. An dem du quasi etwas vorbereitest, was du später überhaupt gar nicht mehr brauchst. Und später wirst du aber nicht deine Arbeit von vorher einfach wegwerfen, sondern du musst dann versuchen, das quasi so umzubiegen, dass du es doch noch verwenden kannst. Und dann hast du am Ende vielleicht schwieriger wartbaren Code, als du eigentlich hättest, wenn du es erst mal so gelassen hättest.
Theo
Ja, und was meinst du mit schwieriger wartbar im Detail?
Martin
Weil du die Abstraktion, die du vorher gebaut hast, jetzt anders verwendest, als du es ursprünglich mal angedacht hattest, als du die Zukunft noch anders ausgemalt hast, als sie jetzt Gegenwart geworden ist.
Theo
Okay, das klingt für mich gerade noch ziemlich abstrakt. Sebastian, hast du vielleicht ein gutes Beispiel, um das Ganze ein bisschen greifbarer zu machen?
Sebastian
Also naja, wir können ja mal, man kann zum Beispiel sagen, wir wollen einen Taschenrechner programmieren. So ein Taschenrechner beispielsweise, der muss verschiedene Grundrechenarten beherrschen. Und jetzt kann man sagen, man fängt halt an mit der Plus-Operation beispielsweise. Und dann könnte man halt sagen, okay, ich schreibe eine Funktion, die kriegt eine erste Zahl und eine zweite Zahl und die verrechnet die. Und jetzt könnte man hingehen, schrittweise sagen, okay, aber ich habe im Hinterkopf, ich möchte auch die anderen Grundrechenarten, also Minus mal Durchs beispielsweise bauen. Also könnte man jetzt hingehen und sagen, na okay, ich abstrahier die Funktion. Ich sehe schon mal vor, dass da auch noch die anderen Arten implementiert werden, beispielsweise. Und da könnte ich jetzt hingehen und sagen, ich füge noch eine dritte Eingabe zu dieser Funktion, dritte Parameter zu, wo ich sage, auch noch den Operator, also die Rechenoperation selbst wird noch mit übergeben, beispielsweise. Das könnte beispielsweise so eine Art von Abstraktion sein in einem ganz, ganz kleinen Beispiel. Und im besten Fall sorgt Abstraktion dafür, dass ich sozusagen meinen Kopf klarer strukturiert kriege, also nicht nur meinen Kopf, sondern den Kopf jedes Entwicklers, dass ich sozusagen klarer weiß, also dass ich mich klarer auf ein Teilproblem konzentrieren kann. Aber im schlechtesten Fall sorgt halt Abstraktion dafür, dass ich mehr im Kopf behalten muss, um ein bestimmtes Problem in der Zukunft zu lösen. Das heißt, da muss ich sozusagen sowohl den Inhalt der Kiste als auch das Außenrum der Kiste in Anführungszeichen berücksichtigen, weil ganz salopp gesagt, das, was auf der Kiste draufsteht, mir noch nicht weiterhilft oder nicht korrekt ist oder so. Also das, was die Funktion jetzt technisch gesprochen, was die Funktion als Signatur, als Typen, als Kommentar, als Dokumentation beispielsweise hat.
Theo
Martin, gibt es nach deinem Gefühl so Faustregeln, an denen du persönlich irgendwie festmachst, dass du möglicherweise gerade im Begriff bist, zu früh zu abstrahieren?
Martin
Na ja, grundsätzlich, ich denke, also was ich früher viel gemacht habe, ist, dass ich quasi sobald, also dieses Don't Repeat Yourself, das Trial-Prinzip, wenn man das zu konkret anwendet und sagt, okay, ich habe hier jetzt was, das habe ich doch schon mal implementiert, da müsste ich jetzt das zweite Mal machen und dann abstrahiere ich das erst mal raus und mache mir eine Funktion dafür, irgendwie weiß ich nicht, vielleicht baue ich mir eine Factory, die mir quasi Objekte gibt, die genau das tun, weil ich das jetzt das zweite Mal verwende. So. Und ich habe gelernt, zum Teil schmerzhaft, dass das nicht unbedingt sinnvoll ist, wenn man irgendwie, nur weil man jetzt das was das zweite Mal verwendet, gleich raus zu abstrahieren. Das heißt, um deine Frage zu beantworten, woran ich merke, dass ich zu früh abstrahiere, ich glaube, das merkt man viel zu spät. Also das merkst du nicht in dem Moment, in dem du es tust, sondern das merkst du eigentlich später, wenn du es wieder verwenden willst und merkst, dass du es nicht so abstrahiert hast, dass es wiederverwendbar ist, weil sich die Welt gedreht hat. Das heißt, eigentlich, ich glaube, heute bin ich an dem Punkt, wo ich sage, es ist eher so, dass ich merke, dass ich zu spät abstrahiere, weil ich es seltener tue und dann mehr Arbeit damit habe, weil ich es an vielen Stellen sozusagen ändern muss, aber so Rule of Thump ist, nicht beim zweiten Auftreten gleich abstrahieren.
Theo
Ja, also du wartest quasi immer, bis etwa drei-, viermal geschrieben wurde und wenn du dann das Gefühl hast, jetzt hast du eine Abstraktionsschicht erkannt, dann fängst du erst an mit abstrahieren. Verstehst du das richtig? Genau. So ungefähr. Ah ja. Das ist ja durchaus recht praktikabel. Dann gehst du da ähnlich vor oder hast du da noch ergänzende Methodik?
Sebastian
Ja, es ist immer eine Bauchgefühlsache. Insofern ist es jetzt, finde ich, schwer, davon ganz konkreten Methodiken zu sprechen. Also zwei Dinge, die ich noch hilfreich finde, ist, das eine ist, über, ich sage jetzt mal, etablierte Entwurfsmuster zu schauen. Also wenn ich was baue und ich habe das Gefühl, das geht in die Richtung eines etablierten Entwurfsmusters, dann macht das Sinn, sich das nochmal anzuschauen, zu gucken, okay, kann das passen, kann das nicht passen, weil halt in diesen Entwurfsmustern ganz viel destilliertes Wissen drinsteckt in Bezug auf beispielsweise Erweiterbarkeit und ich sage mal die richtige, in Anführungszeichen, Abstraktion. Also das ist ein ganz konkretes Ding. Ich versuche sozusagen immer diese Entwurfsmuster-Design-Patterns irgendwo mit im Hinterkopf zu haben. So und das aber noch Entscheidendere ist, ich versuche abzuschätzen, ob sich dieser Teil, wo jetzt ich denke, okay, ich brauche jetzt was zum zweiten, dritten, vierten Mal, ob sich das sozusagen perspektivisch aufeinander zubewegt oder voneinander weg bewegt. Also sprich, ob sozusagen der Code, der jetzt gerade relativ ähnlich aussieht, ob der auch in Zukunft ähnlich bleiben wird, dann spricht es für eine Abstraktion oder ob man eher davon ausgeht, dass das sozusagen am Startpunkt noch sehr ähnlich ist, aber vermutlich sozusagen durch zum Beispiel sich verändernde Business-Requirements, Anforderungen, die von außen kommen, in ganz verschiedene Richtungen entwickeln würde. Wenn das der Fall ist, dann würde ich es nicht abstrahieren, sondern eher halt sozusagen Copy-Paste-mäßig erstmal den Code kopieren und dann halt von dort aus anfangen zu entwickeln.
Theo
Spannend. Gibt es nach eurem Gefühl den Grundsatz, dass es schwerer ist, eine verfrühte Abstraktion später wieder aufzulösen, als später eine Abstraktion hinzuzufügen? Oder ist das auch eher so eine Sache von it depends?
Martin
Also ich würde einfach mal reingehen. Also ich persönlich habe das gerade jetzt. Ich reflect eine Code Base, die quasi überhaupt nicht abstrahiert ist. Da war ich jetzt zwei Wochen damit beschäftigt. Und das kann sehr, sehr schmerzlich sein. Also da ist Code wirklich all over the place. Und was ich dort auch gefunden habe, ist halt, dass du zum Beispiel Fehler dadurch hast, dass das Dinge sozusagen falsch kopiert worden sind. Also was ich meine, wenn du alleine das Mark abnimmst und kopierst es halt irgendwie leicht versetzt oder an die falsche Stelle oder mit einer Vertiefung zu viel und dann wird halt versucht mit Style zum rumzuarbeiten. Da hätte wahrscheinlich eine frühere Form der Abstraktion ein cleaner Code gegeben. Jetzt bin ich aber genau in die falsche Richtung gerannt, in dem ich quasi das Ding komplett abstrahiert habe. Also wirklich einmal durch. Durch die Bank weg alles schön Atomik Design mäßig abstrahiert. Und dann festgestellt hat way too much. Also ich habe da Komponenten drinnen, die ich rausgebaut habe, die ich halt wirklich nur an einer Stelle verwende. Und da ist einfach Arbeit reingeflossen, die unnötig war. Das heißt dort eine Balance zu finden ist auch nach Jahren, die man das macht, immer noch schwer. Und ich glaube, es ist beides schwierig. Also es kommt immer ein bisschen auf den Zeitpunkt an. Also ich tendiere momentan ganz aktuell eher dazu später zu abstrahieren als früher. Aber das Pendel kann auch wieder in die andere Richtung schlagen.
Theo
Ja, ich finde diese Frage des Zeitpunkts ganz spannend. Sebastian, macht das aus deiner Sicht einen Unterschied, ob ich mich in einem bereits bestehenden, größeren Projekt bewege oder ob ich jetzt quasi gerade eher in so einer Kickstart-Phase bin, wo das Projekt gerade ganz frisch losgeht.
Sebastian
ja absolut also das ist finde ich ein ganz ganz entscheidender faktor wenn ich also wenn ein projekt gerade startet habe ich noch ganz ganz viele unsicherheiten weiß ich eigentlich noch gar nicht so richtig also ich habe eine zielvision aber ich habe noch ganz viele fragestellungen auf dem weg zu lösen da ist es immer gefährlich tendenziell zu abstrahieren weil man die welt sozusagen noch gar nicht so richtig kennt auf der anderen seite kann sich aber auch lohnen also meistens ist es so dass es in einem gewissen projekt dass es so zwei drei grundannahmen gibt wieso die so das fundament des hauses bilden und das ist ja auch eine form von abstraktion die über die muss man da wirklich wirklich intensiv nachdenken und sich dann dafür entscheiden weil die sind dann später sehr sehr schwer zu ändern also das heißt ich glaube im beginn des projektes gibt es quasi wenige abstrack sollten es wenige abstraktionen sein aber die müssen dafür sehr sehr durchdacht und sehr robust sein und und da würde ich vor allem auch versuchen solche ad hoc abstraktionen zu vermeiden also so dieses hier ich sehe jetzt irgendwie zwei kurzstellen sind irgendwie so ein bisschen ähnlich ja da machen wir mal abstraktion das würde ich bei einem frühen projekt lebenszyklus wirklich tun nichts vermeiden wenn das projekt weiter in der zukunft ist dann dann kennt man die welt da besser dann weiß man besser ob die annahmen die man getroffen hat so stimmen und so weiter da wird man da ist man eher auf der detail ebene unterwegs man wird beim haus eher sozusagen die räume anmalen oder die räume fein gestalten und dann wird man quasi in diesem bereich vielleicht abstraktionen finden aber die haben nicht mehr diesen großen also die haben keine auswirkung in der regel mehr auf das ganze haus sozusagen das heißt deshalb ist es da weniger risiko reichen abstraktionen einzuführen wenn das projekt später ist die abstraktion haben auch einen großen vorteil muss man sagen weil weiß einem natürlich wie martin ja gerade schon gesagt hat es hilft das am ende effizienter zu werden wenn man sie auch an der in anführungszeichen richtigen stelle eingebaut hat
Theo
Also effizienter im Sinne von, du kannst Dinge wieder verwenden und wenn du über Code nachdenkst und diese Abstraktion als Blackbox betrachtest, dann musst du nicht über die Interna nachdenken, dann kannst du sie wie eine Art interne API verwenden.
Sebastian
Genau, also das ist, glaube ich, das Entscheidende von der Abstraktion oder woran man merkt, wir haben ja, wir haben jetzt über schlechte Abstraktion viel geredet, aber die Frage ist ja, woran erkenne ich eine gute Abstraktion, das ist auch eine spannende Frage. Und ich glaube, das ist genau das, was du gerade beschrieben hast, das muss möglich sein. Also ich kann quasi einen Teil meines Programms, nämlich der Teil, der abstrahiert ist, als als als Black Box, als schwarze Kiste, wo ich sozusagen nur Anschlüsse habe, die richtig und gut beschriftet sind und wo es auch nicht so viele von gibt, betrachten und dann kann ich damit Dinge bauen. Also Beispiel, dass das eher so ist wie Lego Steine, die sozusagen zusammen passen. Und ich muss jetzt nicht anfangen, quasi irgendwie, keine Ahnung, mein Holzstück zu fräsen, sodass ich da irgendwie Zeug aneinander passen kann, sondern Lego hat das halt so vorgenommen. Das ist das Beispiel für eine gute Abstraktion.
Theo
Ja. Okay, ich glaube, damit haben wir das Thema eigentlich ganz gut umrissen. Martin, möchtest du zum Thema verfrühte Abstraktion noch etwas ergänzen?
Martin
Ich wollte sowieso mal reinspringen, ich fand nämlich ganz spannend was ein Stichwort was der Sebastian gerade gesagt hat und zwar das Thema Grundannahmen und das Fundament der Software, das Fundament des Hauses was wir da bauen und da ist ein Aspekt den ich, also wo ich finde dass wir häufig, also ich sehe das häufig als Developer, ich selbst nehme ich da nicht aus, zu oft nicht in die Abstraktion sondern zu oft zu früh in die Konkretisierung gehen, also es ist eine andere Art quasi der verfrühten, nicht Abstraktion sondern Konkretisierung, dass quasi wir anfangen Dinge umzusetzen die vielleicht noch gar nicht vollkommen durchdacht sind, das heißt was ich sehr sehr gerne mache und auch wieder jetzt vermehrt mache ist, dass ich mich wirklich erst mal im Zettel und Stift hinsetze und versuche dieses Fundament herauszuarbeiten bevor ich anfange irgendeinen Code zu schreiben und das ist halt für mich das Gegenteil von verfrühten Abstraktionen, wenn ich dann, wenn ich das nicht mache, denn das ist verfrühte Konkretisierung.
Sebastian
Ja, ich finde schon, also das ist für mich eigentlich so ein, also mir hilft es auch total, nicht nur über ein Problem nachzudenken, weil da, ich sag mal, da kann man zu schnell in diesen Modus oder kann ich auch zu schnell diesen Modus verfallen, ja ja, ich weiß ja eigentlich, was ich will und was ich machen will, sondern das halt ein Bild zu malen, es hinzuschreiben, es mal zu versuchen, kohärent jemandem zu erklären, das sind alles Dinge, die da helfen können, um sozusagen in diesen Slow-Thinking-Modus zu kommen, um quasi langsam über das Problem nachzudenken, um intensiv über das Problem nachzudenken und um auch mal das Problem besser von verschiedenen Seiten betrachten zu können und damit findet man tendenziell bessere Abstraktionen und die, ich sag mal, die richtigen, würde ich auch sagen, ja.
Martin
Also ich denke, genau das, was du gerade gesagt hast, Slow Thinking, ist sozusagen die Antwort auf Theos Frage von vorhin, wie man verfrühte Abstraktion erkennen oder vermeiden kann. Also, finde ich super.
Theo
Okay, super. Dann nehmen wir das mit Slow Thinking über ein Problem erst mal durchdenken, bevor man direkt in den Code steigt. Das hört sich so banal an.
Sebastian
Das hört sich so banal an und das ist auch nicht, also wie soll ich das sagen, das klingt auch so wie ja, alle anderen denken ja nicht, so soll das gar nicht klingen, im Gegenteil. Also das ist ziemlich schwierig, das wollte ich noch mal sagen, also Slow Thinking ist nicht einfach, im Gegenteil, das ist das Denken, was sozusagen die höchste Konzentration, die höchste Ruhe, die höchste Anstrengung für den Kopf erfordert, dieses wirklich methodische, strukturierte, wohlüberlegte, in Ruhe über Dinge nachdenken, aber ich glaube, das ist halt, da ist eine unglaubliche Kraft drin, das ist auch sehr, sehr wertvoll und das ist glaube ich sehr, sehr, also das finde ich sehr bereichernd auch und das macht auch einen großen Spaß.
Martin
Du sprichst von Kahn, genau, der hat das.
Sebastian
spricht von Karlemann. Genau, der hat das geprägt quasi, genau, ja.
Theo
Kahnemann ist jetzt für die Hörerinnen und Hörer, müsst ihr natürlich kurz sagen, worüber ihr hier sprecht.
Martin
Hat ja nicht sogar einen Nobelpreis bekommen. Auf jeden Fall ist das jemand, der ein Buch geschrieben hat über die zwei Arten des Denkens, Slow Thinking und Fast Thinking. Genau. Und das Fast Thinking ist halt das, was wir machen, wenn wir Mustererkennung machen und wenn wir so durch den Alltag gehen und alles relativ einfach in unserem Kopf einordnen können und wenn wir auf neue Dinge treffen, die uns erstmal stressen, weil sie neu sind, das ist einfach so für uns Menschen, dann verfallen wir in einen analysierenden Modus und unser Kopf beginnt langsamer zu denken, quasi in größeren Schleifen zu laufen. Und dieses langsame Denken ist aber etwas, was für uns extrem anstrengend ist. Also, irgendwie Jetpiloten und so, die sind halt unter permanentem, extremen Stress, weil die halt quasi dieses Slow Thinking in ihrem Alltag haben. Genau. Und dazu kann man sich aber auch trainieren, dass man umschalten kann, auch wenn man meint, man ist in einem Prozess, in dem Mustererkennung ausreicht, zurücktreten, umschalten in Slow Thinking und den Prozess nochmal frisch analysieren, das ist etwas, was man lernen kann. Also, da ist halt das Buch von Kahnemann sehr hilfreich, um da mal reinzuschäulen.
Theo
Wir werden auf jeden Fall mal, denke ich, einen Link auf das Buch mit in die Shownotes packen. Dann können die Hörerinnen und Hörer da noch mal näher nachgucken. Okay, gut. Ich würde, glaube ich, unter dem Thema verfrühte Abstraktion jetzt mal so einen Strich machen und tatsächlich zu unserem zweiten kleinen Thema noch übergehen, zu einem Namensvettern der verfrühten Optimierung. Sebastian mag sich vielleicht ganz kurz erläutern, damit wir darunter verstehen.
Sebastian
Naja, im Prinzip, also bei Optimierung geht es in der Regel um sozusagen das Verbessern des Programms in einer Art und Weise, dass es danach beispielsweise schneller ist. Das ist eigentlich das Typischste, dass ich sozusagen mehr, also dass die Leute weniger lang warten müssen, wenn sie auf eine Webseite gehen, beispielsweise, dass bestimmte Geschäftsprozesse schneller ablaufen, dass ein höherer Durchsatz erfolgt, also dass wir sozusagen mehr Daten durchbekommen in einer kürzeren Zeit, beispielsweise. Darum geht es meistens bei Optimierung. Und wie soll ich sagen, die Gefahr ist, dass man, also oder anders, wenn man programmiert, hat man ja gewisse Annahmen, wie man, wie schnell der Programm, das Programm ist, was man gerade schreibt sozusagen. Und es ist häufig so, dass Leute schon sozusagen, also es gibt es wieder in beiden Extremen. Es gibt sozusagen das Extrem, dass man viel zu spät optimiert und dann ist es sozusagen ist es extrem schwierig, da noch zum Beispiel mehr Geschwindigkeit rauszuholen. Und dann gibt es aber auch den Fall, der ist auch sehr häufig, dass man quasi das Falsche optimiert, dass man schon ganz intensiv irgendwie sich eine Code Stelle nachguckt und die optimiert. Und dann ist es aber, wie sich später herausstellt, gar nicht die Stelle, die das Problem eigentlich, also die ein Großteil, also die zum Beispiel langsam ist, sondern ist eigentlich eine Stelle, die eigentlich schon schnell geht. Und das Problem dabei ist, ist, dass sozusagen optimierter Code meistens in irgendeiner Form schlechter lesbar ist und quasi komplizierter ist auf irgendeine Art und Weise.
Theo
Ah, okay. Das heißt, du würdest, wenn ich dich richtig verstehe, ziehe ich da jetzt raus, du würdest tendenziell vorschlagen, an der konkreten Anwendung, also natürlich bestimmte Problematiken sollte man im Hinterkopf behalten, damit man nicht in Performance Pitfalls irgendwie reinfällt. Auf der anderen Seite sollte man aber letztendlich tatsächlich schauen, welche Performance-Probleme für den Nutzer spürbar sind und diese Stellen gezielt optimieren, richtig? Genau, also...
Sebastian
Genau. Ich glaube, was total wertvoll ist, ist eine Vorstellung zu haben, mit wie vielen Daten arbeite ich gerade. Also wenn ich zum Beispiel über einen Array von Daten irgendwie was mache, da drüber gehe, Schritt für Schritt, dass ich eine grobe Vorstellung habe, sind da 10, 100, 1000 oder 10 Millionen Elemente drin. Und umso krasser, wenn ich mehrere Arrays ineinander habe, sozusagen. Also wenn ich zwei, drei, vier Schleifen ineinander habe, dann ist es auf einmal ganz, ganz kritisch, dass ich mir bewusst bin, wie viele Elemente sind auf jeder Ebene sozusagen vorhanden. Das ist, glaube ich, was, das sollte man versuchen. Und das ist auch eine wichtige Grundannahme in Systemen, mit wie viel Daten sie grundsätzlich arbeiten können. Und die andere Seite ist aber genau das, was du gemeint hast. Ansonsten muss man halt messen, messen, messen, was am Ende das Problem ist. Weil das Problem kann in deinem Nutzercode sein. Das kann an den Schnittstellen liegen. Also es kann auch sein, dass Dinge langsam sind, weil man also was sozusagen nichts mit unserem Code zu tun hat, sondern mit der Art und Weise, wie der Code installiert ist beispielsweise. Oder da gibt es halt wirklich alle, alle möglichen Fälle, warum Dinge langsam sein können. Und das muss man halt wirklich messen, um dann rauszufinden, woran es denn liegt sozusagen.
Theo
Spannend, würdest du vielleicht für die Hörerinnen und Hörer als Kontext, Sebastian, du bist ja maßgeblich an Neos, unserem geliebten Open-Source-System, es beteiligt und das heißt, da bist du auch im Framework-Flow, das heißt, du bist quasi auch nicht nur in der Anwendungsentwicklung in der klassischen unterwegs, sondern auch in der Framework- und Library-Entwicklung, würdest du sagen, dass da Performance-Optimierung irgendwie tendenziell noch wichtiger ist?
Sebastian
Es ist auf jeden Fall schwieriger, weil man die Anwendungsfälle nicht so klar umreißen kann. Wenn man halt einen Werkzeugkasten baut, dann ist man sozusagen nicht in einem ganz konkreten Anwendungsfall. Und es geht darum, den schnell zu kriegen, sondern muss letztendlich die meisten Anwendungsfälle schnell bekommen, für die sozusagen das Werkzeug da ist, also im Beispiel von Neos oder von Flow. Und das ist tatsächlich viel, viel schwieriger. Ich sag mal, im Open Source Bereich haben wir so diesen, also im Neos Projekt haben wir so diesen Spruch, wir müssen es dreimal bauen, damit wir es richtig bauen, in Anführungszeichen. Also das ist halt wirklich, ich sag mal, ein langer und auch relativ schmerzhafter Prozess. Also im Sinne von, dass wir halt auch wirklich große Teile dann nach mehreren Jahren, wo mehrere Jahre Entwicklung reingeschlossen ist, dann nochmal wegschmeißen und neu machen müssen, um halt dann da besser zu werden. Aber das, ich sag mal, macht auch viel Spaß auf der anderen Seite, weil man diese Art von Problem halt im kommerziellen Kontext eher nicht in dieser Tiefe hat, muss ich sagen.
Theo
Ja, aber würdest du sagen, dass du, wenn du eine Library schreibst, tendenziell früher optimierst? Also dass du versuchst, stärker vorauszudenken noch als bei einer Anwendung oder ist es meinset eigentlich das gleiche?
Sebastian
Naja, also es ist schon, nee, also ich würde sagen, das Mindset ist grundsätzlich das Gleiche. Ja, nee, das Mindset ist, also es bringt halt auch nichts, zu früh viele Annahmen zu treffen. Man muss halt, ich glaube, das Wichtige ist halt bei einem Framework, man muss sich halt bewusst sein, dass die Leute es vielleicht anders nutzen, als man das ursprünglich gedacht hat. Und das wird man irgendwann merken, wenn das Framework wirklich genutzt wird. Also, weil die Leute ja dann Backreports schreiben, weil sie dann Edge-Cases sagen, hey, das haben wir nie bedacht. Und ich sage mal, das ist, man kann das versuchen, das zu antizipieren und das vorherzusehen, aber das ist super, super schwierig. Also ich meine, es ist schon so oft passiert, dass ich gedacht habe, ich habe das Problem schon durchdrungen und habe dann sozusagen Version 1 rausgebracht. Und dann kamen dann ein paar Wochen später irgendwelche Issues, Pull Requests, sonstiges, wo man dann auch festgestellt hat, oh Mist, nee, wir müssen eigentlich nochmal zurückgehen, weil die Leute es halt auch in einer anderen Art und Weise einsetzen und auch in einer sehr validen Art und Weise einsetzen, die man einfach null auf dem Schirm hatte am Anfang. Also.
Theo
Spannend. Martin, du hattest im Vorgespräch nochmal etwas angedeutet, das fand ich auch ziemlich spannend. Und zwar hattest du gesagt, dass du abseits dieser klassischen Formen von Optimierung, über die wir jetzt gerade gesprochen haben, die sich quasi in der Form bewegt, dass man Code optimiert, dass du für dich so ein großes Stichwort noch das Thema Data Optimization ist. Magst du vielleicht ganz kurz nochmal darauf eingehen, was du damit meinst?
Martin
Hm.
Theo
Oder machen wir da jetzt ein zu großes Fass auf?
Martin
Da machen wir ein ziemlich großes Fass auf. Ich würde auch gerne nochmal, bevor wir dahin kommen, oder wenn wir das überhaupt, vielleicht ist das auch nochmal ein eigener Podcast, ich wollte gern nochmal auf diese verfrühte Optimierung, weil, also wir haben ja bis jetzt nur über Optimierung gesprochen und nicht so richtig über verfrüht. Und für mich, also es gibt halt zwei Aspekte bei dem ganzen Punkt verfrühte Optimierung des Codes. Und das ist zum einen natürlich das, ich sag mal, das Schreiben, also ich gucke auf meinen Code, stelle fest, an irgendeiner Stelle hängt es und da verbrauche ich relativ viel Zeit oder da fließen halt viele Daten oder wie auch immer. Und das ist die eine Seite, das ist das, worüber wir gerade schon gesprochen haben. Das andere, was ich aber auch sehr, sehr spannend finde, was Sebastian kurz angerissen hat, ist der Punkt tatsächlich mit Codesign solche Probleme zu überschlagen oder zu erschlagen. Ich glaube, dass es tatsächlich ganz, ganz wichtig ist oder für mich persönlich ist es viel, viel wichtiger, mir eine Art von Codes-Steel anzugewöhnen in meiner ganz normalen täglichen Arbeit, die quasi bestimmte Sachen verhindert, also gerade, was du vorhin gesagt hast, irgendwie, wenn ich vier Schleifen hintereinander habe, dann ist das vermutlich langsam. Das hat so, also ich habe das direkt vor mir gesehen, wie das aussieht und dachte mir so, was ist das denn? Genau und das ist, ich glaube, da kann man, also wenn es um verfrühte Optimierung geht, ich denke, man kann sehr, sehr gut vorarbeiten und das ist niemals verfrüht, über seinen Codes-Steel nachzudenken und da vielleicht auch zu lernen und zu investieren, vor allem Zeit zu investieren, sich damit auch aneinanderzusetzen und was dann das tatsächliche Optimieren von Code angeht, also ich, also ich bin ja viel im Functional Programming-Bereich unterwegs und drehe da auch ab und zu mal gerne drüber und das Ding ist, das erste Argument, was immer kommt, ist, ja, aber das ist ja langsam und ich kann mich hier hinstellen und kann sagen, ich habe in meinem Leben noch nicht ernsthaft Performance-Optimierung auf Code gemacht, der fertig geschrieben war, weil das übernimmt der Compiler für mich eigentlich sehr, sehr gut, das heißt, ja, man hat mal eine Stelle, wo es klemmt, aber das ist dann meistens tatsächlich was, wo man einfach den Code noch nicht genug durchdacht hatte, also ich weiß nicht, wie es euch da geht, aber ich persönlich habe irgendwie, sobald ich anfange, darüber nachzudenken, wie ich hier irgendwie noch eine Sekunde rauskriege, damit der Code da schneller läuft und da anfange, irgendwelchen Lirn-Codes zu schreiben, dann ist das meistens, wo ich erstmal einen Schritt zurück trete und denke, okay, ja, so, das ist einfach noch nicht verstanden.
Sebastian
Also ich würde sagen, die Kernfrage ist eigentlich, oder für mich ist die Kernfrage, sagen wir es mal so, warum muss dieser Code überhaupt laufen? Also das ist, also wenn ich, wenn jetzt eine Anwendung langsam ist und man guckt sich an, was die so tut, dann ist eigentlich die Frage, ist das, macht sie das jetzt gerade zum richtigen Zeitpunkt oder kann sie das schon, kann sie gewisse Zwischenergebnisse schon vorher berechnen und dann permanent da behalten, beispielsweise. Kann man sich Zwischenergebnisse merken, beispielsweise kann man, was in Funktionale Programmierung ja wunderbar geht durch die Nutzung von entsprechenden Datensstrukturen, dass man halt sich Zwischenergebnisse ohne Probleme merken kann und damit halt auch viel Berechnung sich später sparen kann. Ich glaube, sowas ist halt, finde ich, immer noch ein wichtiges, wichtiger Aspekt. Und das ist auch so ein bisschen die Krux. Wenn man, ich sage mal, wir haben ja, um vielleicht nochmal den Bogen zu schlagen zur Abstraction hin, gute Abstraktion hilft später beim Optimieren. Schlechte Abstraktion behindert massiv beim Optimieren. Also das heißt, die beiden Seiten hängen irgendwo miteinander zusammen. Wenn ich irgendwo, ich sage mal, gut geschnittenen, gut abstrahierten Code habe, dann kann ich ihn auch später noch optimieren und kann da noch Dinge rausholen und Performance rausholen, indem ich sozusagen an ein paar Ebenen, an ein paar Stellen Stellschrauben einbaue, aber ohne dass sich das sozusagen für den Nutzer nach außen halt verändert. Also beispielsweise, wir haben damals mal im Neos-Projekt eine Templating-Sprache gebaut, nennt sich Fluid, die war halt, da hat man halt, da muss man HTML mit so speziellen Markern halt parsen, also sozusagen analysieren und dann halt ersetzen, diese Marker. Und im ersten Schritt haben wir zum Beispiel das so gemacht, dass wir das halt ganz billig, jedes Mal bei jedem Aufruf haben wir halt dieses HTML genommen, haben das verhackt, haben sozusagen nach diesen Markern gesucht, für jede einzelne Anfrage. Und uns war klar am Anfang, dass das relativ zeitig, dass wir das ändern müssen, also das war auch schon eine Grundannahme, aber wir konnten trotzdem schon mal einige Monate damit fahren und damit arbeiten sozusagen und was wir dann später machen konnten ist, wir haben sozusagen diese Seite genommen, das zerhackte Zwischenergebnis quasi genommen, haben uns das weggespeichert, haben daraus letztendlich PHP-Code generiert und das war halt um ein Vielfaches schneller als dieses jedes Mal zu parsen beispielsweise. Und das interessante dabei ist, dass diese Art von Anpassung haben die Endnutzer gar nicht gemerkt, weil wir die sozusagen schon, weil sozusagen da in Anführungszeichen an der richtigeren Stelle geschnitten wurde und damit ist sowas halt möglich. Das wäre vielleicht nochmal so ein ganz konkretes Beispiel, wo so eine Optimierung halt, würde ich sagen, gut gelaufen ist. Genau, aber trotzdem ist halt immer die Frage, was kann ich weglassen, was kann ich vielleicht, wenn ich Zeit rauskitzeln will, welche Sachen kann ich denn, muss ich denn nicht machen vielleicht.
Theo
Ja, okay, gut, dann machen wir jetzt hier einen Strich drunter. Ich glaube, auch die wichtigsten Sachen wurden gesagt. Ansonsten Martin, Sebastian, möchtet ihr gerne noch irgendetwas Wichtiges loswerden zu einem der beiden Themen?
Sebastian
Ad hoc jetzt nicht.
Theo
Ad hoc jetzt nicht. Gut, im Zweifelsfall machen wir noch eine weitere Folge. Okay, dann vielen, vielen, vielen Dank. Das waren sehr, sehr spannende Insights. Danke, Martin. Danke, Sebastian.
Sebastian
Danke dir, hat Spaß gemacht.
Martin
Danke dir.
Theo
Danke auch an die Hörerinnen und Hörer und bis nächste Woche, würde ich sagen.
Sebastian
Ciao.
Martin
Bis dahin.