Aussterbender beruf des tages

Jornalist… so viel gehirn scheint man dafür nicht zu brauchen, dass nicht ein kompjuter diese standardtexte schreiben könnte.

Ich wünsche euch allen auch weiterhin viel spaß beim festen glauben an die von CDU, SPD, CSU, AFD, FDP, scheißgrünen und der linken propagagierte „vollbeschäftigung“, denn die hält in ihrem lauf weder ox noch esel auf. Schade nur, dass so viele menschen, deren arbeit niemand bezahlen will, wohl noch jahrzehntelang durch ein staatliches sankzjonssystem terrorisiert werden, während mit immer weniger menschlicher arbeit immer mehr güter, dienstleistungen und gesellschaftlicher reichtum produziert wird. Wenn fortschritt überhaupt einen sinn haben kann, dann ist es der sinn, den menschen die leidige arbeit abzunehmen.

Und hej, es besteht sogar eine schangse, dass der kompjuterjornalismus seriöser, weniger manipulativ und weniger dumm wird, als es die tätigkeit von gemieteten milljardärsfedern mit sendungsbewusstsein und propagandaabsicht ist. :mrgreen:

Aussterbender beruf des tages

Fernfahrer… auch so eine stumpfe maloche, die niemand ernsthaft vermissen wird.

Wie sich diese Zukunftsvision darstellen könnte, zeigt nun die schwedische Firma Einride, die mit dem Prototyp T-Pod einen Vorschlag für einen selbstfahrenden batterie-elektrischen Warentransporter macht

Ich wünsche auch weiterhin ganz viel spaß beim festen glauben an das p’ltische versprechen der „vollbeschäftigung“ und die ausweitung des hartz-IV-terrors.

Technischer fortschritt des tages

Gemäß planungen von siemens gibt es im jahr 2019 eine fabrik, in der die autos vom band rollen, ohne dass ein mensch dort seine begrenzte lebenszeit mit arbeit verschwenden muss. Und morgen labern die rückwärtsgewandten, mittelalterliebenden scheißp’litiker und ihre meist jornalistischen speichellecker wieder von der vollbeschäftigung und davon, dass man den hartz-IV-terror noch viel härter machen muss, damit jeder entweder um arbeit bettelt oder sich einfach selbst umbringt. Denn sozjal ist, was arbeit schafft, und arbeit macht frei.

Prof. dr. Offensichtlich

Prof. dr. Offensichtlich hat jetzt bei einem dschobb bei der deutschen bank rausgekriegt, dass technischer fortschritt darin besteht, dass arbeit von maschinen und nicht mehr von menschen ausgeführt wird. Da hat er sich aber nicht gefreut, dass fortan der gleiche gesellschaftliche wohlstand mit weniger mühsamer menschlicher arbeit hergestellt wird, sondern bekommt gleich böse albträume, dass es uns allen schlechter gehen würde. Der kann sich halt nicht vorstellen, dass zwangsläufig eine andere gesellschaft daraus entstehen muss.

Warum ich die libc hasse!

Nachtrag: ja, die überschrift ist ein „bisschen“ irreführend, und ich meine die glibc. Aber die hasse ich wirklich jeden tag ein bisschen mehr.

Ja, ich weiß, das ist jetzt ein ziemliches friek-tema. Aber ich hasse die normale libc (und könnte Fefe unentwegt für seine dietlibc küssen) und möchte mir unbedingt mal das bisschen luft verschaffen.

Das ich die glibc hasse, liegt daran, dass ich mein eigenes c-gehäcksel manchmal statisch binde, also keine shared libraries verwende, sondern ein binary haben möchte, das ich „einfach so“ auf einem anderen rechner verwenden kann. Ich sitze an ständig wexelnden geräten, und ich habe auch nicht überall eine entwicklungsumgebung zur verfügung oder die erforderlichen rechte, nach belieben softwäjhr nachzuinstallieren — einmal ganz davon abgesehen, dass ich die installazjon eines laufenden sörvers nur anfasse, wenn es gar nicht anders geht. Da ist es für mich oft das günstigste — meine eigenen, unentbehrlichen tuhls habe ich auf einer speicherkarte ständig bei mir — wenn ich ein binary habe, dass ich auch starten kann, selbst wenn bestimmte shared libraries nicht installiert sind. Die meisten libraries, die ich verwende, sind relativ klein, so dass dieses „vergnügen“ nicht zu „teuer“ wird.

Bis auf diese verdammte libc! Machen sich heutige programmierer eigentlich gar keine mühe mehr, bloatware zu vermeiden?

Nehmen wir einmal ein beispiel. Der folgende, sehr schlichte „programm“ ist eine kleine abwandlung eines klassischen lehrbuchbeispiels.

#include <stdio.h>
#include <stdlib.h>

int
main (int argc, char **argv)
{
  const char *s = "Hallo Welt";
  puts (s);
  return EXIT_SUCCESS;
}

Speichern wir es einmal unter dem namen hello.c. Wenn dieses programm mit der anweisung…

cc -s -Os hello.c -o hello

…kompiliert wird (-Os optimiert den erzeugten kohd auf geringe dateigröße, und -s entfernt die symboltabelle und andere für die lauffähigkeit nicht benötigte verwaltungsinformationen vom erzeugten binary), denn ist das ergebnis ja noch durchaus plausibel, wie ein anschließender ls -l verrät:

-rwxr-xr-x 1 elias elias 5652 2010-11-05 18:51 hello
-rw-r--r-- 1 elias elias  145 2010-11-05 18:29 hello.c

Fünfeinhalb kilobyte für eine schlichte textausgabe ist zwar ein bisschen mehr, als man von „einfachen“ betriebssystemen gewohnt ist, aber der startup code für so einen aufgeplusterten pinguin ist ja auch nicht trivial.

Die für die ausgabe verwendete funkzjon puts — ich habe für dieses beispiel mit absicht nicht printf verwendet, weil printf eine menge weiteren kohd benötigt, um die im formatstring angegebenen formate zu interpretieren — sollte relativ einfach implementiert sein, vielleicht ungefähr so¹:

/* Einfache beispielimplentazjon der standard-funkzjon puts */
int
puts (const char *s)
{
  register int c, n;
  for (n = 0; putchar ((c = *s) == 0 ? '\n' : c) >= 0 && c != 0; ++s, ++n)
    ;
  return ferror (stdout) ? EOF : n;
}

Nichts ist darin, was ehrfurchtgebietende komplexität erwarten lässt. Dieses ferror sollte einfach nur ein fehlerbit im FILE *stdout prüfen und im fehlerfall eventuell errno setzen und einen wert ungleich 0 zurückgeben; und dieses putchar ist ein makro, das ein zeichen an einen ausgabebuffer anfügt, einen index für die näxste bufferposizjon erhöht und gegebenenfalls den buffer mit write wegschreibt und anschließend den index für die näxte zeichenposizjon zurücksetzt. Ich könnte hier jetzt auf die schnelle ein beispiel angeben, wie man so etwas als makro implementieren kann, aber das würde durch die schwer lesbare verschachtelung einiger ?-operatoren (buffer voll? zeilenbufferung?) nicht gerade deutlicher als die verbale beschreibung, und deshalb lasse ich es.

Kurz gesagt: Es ist zu erwarten, dass diese puts-funkzjon nicht wesentlich mehr als — sagen wir einmal — 1000 bytes objektkohd erzeugt. Sie ist völlig trivial. Eine dereferenzierung, ein test auf das nullbyte am stringende und ein verhältnismäßig einfaches makro bilden die innere schleife, am ende wird der rückgabewert durch einen bit-test ermittelt, damit fehler an den aufrufenden kontext gemeldet werden können. Als zusätzlicher kohd kommen die vier bytes für die globale variable int errno hinzu und natürlich die funkzjon write für die native, ungebufferte ausgabe, die direkt an den kernel weitergeleitet werden sollte (natürlich wird auch hier anschließend errno gesetzt, wenn ein fehler auftrat — aber auch das sind auch nur eine handvoll bedingungen).

Nun, bei der libc, die mit einem normalen GNU/linux-system (in diesem fall eine debian-distribution) daher kommt, sieht das offenbar ein bisschen anders aus. Mit dem folgenden aufruf…

cc -s -Os -static hello.c -o hello

…kann man eine statisch gebundene versjon dieses schlichten hallo-welt-programmes erzeugen, das völlig bewusst so formuliert wurde, dass es nur eine triviale und den kohd nicht aufblähende funkzjion verwendet. Ein anschließendes ls -lh lässt einem die kinnlade herunterklappen und bei empfindlichem magen den mageninhalt nach oben steigen:

-rwxr-xr-x 1 elias elias  510K 2010-11-05 21:34 hello
-rw-r--r-- 1 elias elias   145 2010-11-05 18:29 hello.c

WTHF! 510 KiB für das dazulinken von ansich völlig trivialem kohd ist doch eine menge holz. 😦

Den blick in die (nicht gerade schnell erfassbaren) kwelltexte der libc, um diesem bloat auf die spur zu kommen, erspare ich mir mal. Stattdessen hier eine schnellere und schlampigere analyse, die auch schon erschüttert:

Lässt man die opzjon -s beim kompeiler-aufruf einmal weg, um die symboltabelle im binary zu belassen, kann man sich hinterher mit nm -g hello | awk '$2 == "T"' anschauen, welche symbole in der kohd-sekzjon des kompilates enthalten sind; und das zeigt wiederum, welche funkzjonen der linker dazugebunden hat, weil sie von der einzigen verwendeten funkzjon puts verwendet werden. Wer jetzt meint, dass sich seit den siebziger jahren doch einiges in sachen komplexität einer standard-ein-ausgabe getan haben könnte und dass die implementazjon von puts vor allem deshalb „ein bisschen“ fett geworden ist, der kann mir bitte einmal erklären, warum (unter anderem, denn ich nenne hier nur einige besonders absurde beispiele) die folgenden funkzjonen für die schlichte ausgabe einer nullterminierten zeichenkette benötigt werden sollten:

  • bsearch
    Wozu zum abgehackten pimmel nochmal benötigt die libc dafür eine binäre suche? Selbst beim wildesten spekulieren fällt mir kein grund ein, warum die benötigt werden sollte.
  • dprintf
    Hui, den printf für die direkte ausgabe in dateideskriptoren, den sieht man wirklich selten in „echtem“ kohd…
  • fprintf
    Haben die beim häcken der libc etwa die triviale standardfunkzjon puts (s) mit einem printf ("%s\n", s) implementiert? Das würde den ganzen bloat ja erklären. Aber es wäre auch so gnadenlos dumm, dass einem nichts mehr dazu einfällt.
  • localtime
    Was zum schwefelkackenden höllenhund?!?!
  • open_memstream
    Wozu soll hier eine ein-/ausgabe in einen speicherbereich benötigt werden? Die puts-funkzjon ist trivial und bedarf derartiger abstrakzjonen des stream-konzeptes nicht.
  • qsort
    OMFG! Was soll bei diesem einfachen vorgang bitte durchsortiert werden!?
  • setlocale
    Soll da etwa die ausgabe von einzelzeichen in einem stream an die landeseinstellungen angepasst werden?
  • sscanf
    Mir fehlen die passenden derben worte, um dazu noch etwas sagen zu können. m(

Wie gesagt, dass alles für die ausgabe einer nulltermierten Zeichenkette nach stdout.

Diese allgemein bekannten funkzjonen werden natürlich ergänzt um einen wust von internen funkzjonen, mit denen diese standards implementiert werden. Es ist einfach unfassbar. Wer immer an der libc herumprogrammiert hat, er schien sich gesagt zu haben, dass ruhig ein anständiger bloat entstehen kann, sein kompjuter hat ja kein problem damit. Und deshalb wurde jede disziplin abgelegt und man hat sich allgemein einen dreck darum geschert, ob bloat entsteht oder nicht. Und die meisten programmierer, die so einen dreckskohd nutzen, merken es niemals, weil ja der ganze bloat schön in einer dynamischen bibliotek versteckt bleibt und nicht die größe des binary aufbläht. Dass es speicher frisst und auf die performanz geht, drauf geschissen! Dass bei einer zentralen bibliotek wie der libc jedes einzelne programm von diesem bloat betroffen ist, dass es also eine last für das gesamte system wird, drauf geschissen! Sorgfalt und sparsamkeit waren gestern, lasset uns gewaltige mengen RAM voraussetzen und überall, wo dieses nicht wie vorausgesetzt vorhanden ist die platten auf die auslagerungspartizjon kratzen und gebet der CPU extrafette brocken kohd für die erfüllung noch der simpelsten und elementarsten aufgaben! Denn das ist die neue zeit, sie ist schäbig, verantwortungslos und schlecht und „erfreut“ zum ausgleich für die kwalitativen missstände im kernsystem mit polierten und effektheischenden benutzerschnittstellen zur verpackung dieser scheiße. So hat man doch etwas zum „freuen“, wenn man von ein paar billigen effekten unterhalten wird, während man sich fragt, warum trotz aller technischen fortschritte der letzten zehn jahre die trägheit der anwendungen gleich geblieben oder gar schlimmer geworden ist.

Und das — so viel noch zum ende — ist leider auch im bereich der freien softwäjhr symptomatisch für die entwicklung in den letzten anderthalb jahrzehnten. Früher einmal habe ich linux geschätzt, weil kompjuter — auch etwas betagtere — viel zu schade zum wegwerfen sind und weil ich eine menge guter softwäjhr auch auf „uralten trümmern“ einsetzen konnte. Inzwischen ist dort in der softwäjhr-entwicklung allerdings der gleiche gleichgültige irrsinn eingekehrt, der auch so prägend für alle anderen plattformen ist. Manchmal hasse ich das alles nur noch!

Die verwendung „moderner konzepte“ macht das ganze noch schlimmer. Wenn man das oben gegebene beispielprogramm einmal zeile für zeile in die hochgejubelte und für beinahe alle „modernen“ projekte verwendete bloatware-sprache c++ überträgt…

#include <iostream>
#include <cstdlib>

int
main (int argc, char **argv)
{
  std::string s("Hallo Welt!");
  std::cout << s << std::endl;
  return EXIT_SUCCESS;
}

…unter dem namen hello.c++ speichert und schnell mit…

c++ -Os -s -static hello.c++ -o hello++

…kompiliert, denn zeigt einem nicht nur die sehr spürbar gewordene wartezeit, die der kompeiler nun benötigt, um sich von diesen recht lächerlichen neun eingabezeilen zu „erholen“, dass hier noch etwas viel schlimmeres geschieht. Auch das anschließende ls -lh ist erschröcklich:

-rwxr-xr-x 1 elias elias 1006K 2010-11-05 21:05 hello++
-rw-r--r-- 1 elias elias   163 2010-11-05 21:09 hello.c++

Dass nach der übersetzung eines lehrbuchmäßig einfachen nullprogrammes nahezu ein MiB kohd benötigt werden soll, nur, um eine kurze zeichenkette in einer std::string-instanz abzulegen und diese zur standardausgabe zu schreiben, das ist wirklich pathologisch. Hier ist der bloat fest ins grundsystem und in die entwicklungswerkzeuge eingebaut, und er „vererbt“ sich von dort auf das gesamte system. Wer sich beim starten eines anwendungsprogrammes wie etwa des beliebten brausers firefox darüber wundert, warum so eine anwendung, die eigentlich nur ein bisschen netzwerkverkehr macht und HTML-dokumente in ein fenster rendert (eventuell ergänzt um den start von plugins, wenn die dargestellte webseit derartige objekte enthält), dafür so viele megabyte speicher belegt, der hat hier einen teil der antwort.

Und wer einen alten, ansich noch funkzjonsfähigen und dienstbaren rechner hat, auf dem sich die „moderneren“ anwendungen gar nicht mehr verwenden lassen; wer sich mit einem derartigen gerät im internetz bewegen will (was ja keine absurde anforderung ist, und was ansich auch keine riesigen ressorßen erfordert)², der ist genötigt, entweder alte, unsichere und in allen ihren bekannten fehlern ausbeutbare softwäjhr zu verwenden (Bog bewahre!), oder aber seinen alten, ansich noch funkzjonfähigen und dienstbaren rechner als sondermüll zu entsorgen und sich einen neuen rechner zu verschaffen.

Und draußen, vor den städten, wäxt das eigentliche monument unserer „zivilisation“: der müllberg. Was die kompjuter darin zu müll gemacht hat, ist allerdings müllsoftwäjhr.

Ach ja, bevor ich es vergesse: das kompilat der hallo.c gegen die dietlibc gelinkt hat bei mir eine dateigröße von 1004 bytes. Es tut das gleiche wie der megabytefette c++-kohd.

¹In wirklichkeit wird puts (s) wohl meist ein makro sein, das fputs (s, stdin) aufruft, aber die implementazjon von fputs ist auch nicht schwieriger. Ich habe das beispiel einfach gehalten, damit die primitivität einer derartigen funkzjon besser sichtbar wird, in einer realen implementazjon einer derartigen library wird ein gewisses augenmerk darauf gelegt werden, keinen kohd zu duplizieren, um sich keine alpträume bei der pflege zu bereiten. Die gleiche betrachtung gilt auch für das putchar-makro, das im regelfall mithilfe des fputc-makros implementiert werden wird.

²Natürlich gibt es immernoch pine und lynx