henry: aus perlcode zeilenvorschübe und Leerzeichen entfernen

Hallo,

ich möchte gerne meinen perlcode verkleinern. Für JS gibt es Onlinetool, das alle unnötigen Zeichen (Leerzeichen, Tabs usw.) entfernt. Das bringt gewaltig was. Ich will keine "Verschlüsselung", geht bei Scriptsprachen sowieso nicht. Nein einfach kompakt den fertigen Code verpacken.
Ich möchte aber keine Verschleierung (Obfuscation). Mein Code soll Code bleiben, vielleicht optimiert.... kann ja sein, aber es soll Code bleiben.

Hat jemand einen aktuelle Link ?

grüsse
          henry

  1. ich möchte gerne meinen perlcode verkleinern. Für JS gibt es Onlinetool, das alle unnötigen Zeichen (Leerzeichen, Tabs usw.) entfernt.

    Minifier heissen die.

    Das bringt gewaltig was.

    … weil JS über das Netzwerk übertragen wird und die einzige Zielgruppe nur noch Interpreter sind, die sich nicht um schlecht formatierten Code scheren. Aber Perl, das normalerweise anders ausgeliefert wird? Und das man g'zippen kann? Ich versteh's nicht.

    Hat jemand einen aktuelle Link ?

    Ich bin bei der Suche nach „perl minifier“ auf die gleiche Frage bei Stackoverflow gestoßen und in einer Antwort dort empfiehlt jemand perltidy mit der Option --mangle.

  2. Magst du auch den Grund sagen?
    Wenn es sich um ein CGI-Skript handelt, das schneller werden soll, bringt stattdessen eine Umstellung auf FastCGI oder mod_perl wirklich was.

  3. Moin Moin!

    Wozu das ganze? Warum glaubst Du, dass das irgendwelche Vorteile hätte? Und vor allem: Welche?

    Wenn Du den Code verschickst, wirst Du den mutmaßlich ohnehin komprimieren. Da fällt etwas mehr oder weniger Whitespace kaum auf.

    Perl kann Whitespace im Code rasend schnell ignorieren. So lange Du Deinen Code nicht mit Megabytes oder Gigabytes an Whitespace aufblähst, wirst Du keinen meßbaren Unterschied beim Starten von Perl feststellen. Wenn Perl erst einmal läuft, arbeitet es mit einer optimierten internen Datenstruktur, in der der Whitespace gar nicht mehr auftaucht.

    Alles, was Du mit so einer Aktion erreichst, ist, dass der Code schwerer zu warten ist als vorher.

    Kleines Beispiel mit dem überfetten CGI-Modul:

      
    /home/alex>cd /tmp/  
      
    /tmp>cp /usr/share/perl5/CGI.pm .  
      
    /tmp>grep CGI::VERSION= CGI.pm  
    $CGI::VERSION='3.64';  
      
    /tmp>bzip2 -c -9 < CGI.pm > CGI.pm.bz2  
      
    /tmp>perl -pe 's/\s+/ /g' < CGI.pm > CGI.pm-stripped  
      
    /tmp>bzip2 -c -9 < CGI.pm-stripped > CGI.pm-stripped.bz2  
      
    /tmp>dir CGI*  
    -r--r--r-- 1 alex users 261357 Jan 25 13:13 CGI.pm  
    -rw-r--r-- 1 alex users 245022 Jan 25 13:14 CGI.pm-stripped  
    -rw-r--r-- 1 alex users  64267 Jan 25 13:14 CGI.pm-stripped.bz2  
    -rw-r--r-- 1 alex users  68378 Jan 25 13:14 CGI.pm.bz2  
      
    /tmp>  
    
    

    Das Entfernen von redundantem Whitespace[1] hat das Modul um 16.335 Bytes kleiner gemacht, die Dateigröße beträgt 93,7% des Originals. Reines Komprimieren drückt die Dateigröße auf 26,2% des Originals. Komprimieren des leicht abgespeckten Codes drückt die Dateigröße auf -- ÜBERRASCHUNG -- 26,2% des abgespeckten Codes bzw. auf 24,6% des Originals, spart effektiv gerade einmal 4.111 Bytes ein.

    Gegenbeispiel mit einem sehr kleinen Modul wie strict:

      
    /tmp>cp /usr/share/perl5/strict.pm  strict.pm  
      
    /tmp>grep VERSION strict.pm  
    $strict::VERSION = "1.07";  
      
    /tmp>bzip2 -c -9 < strict.pm  > strict.pm.bz2  
      
    /tmp>perl -pe 's/\s+/ /g' < strict.pm > strict.pm-stripped  
      
    /tmp>bzip2 -c -9 < strict.pm-stripped > strict.pm-stripped.bz2  
      
    /tmp>dir strict*  
    -r--r--r-- 1 alex users 3933 Jan 25 13:27 strict.pm  
    -rw-r--r-- 1 alex users 3769 Jan 25 13:28 strict.pm-stripped  
    -rw-r--r-- 1 alex users 1932 Jan 25 13:28 strict.pm-stripped.bz2  
    -rw-r--r-- 1 alex users 2009 Jan 25 13:28 strict.pm.bz2  
      
    /tmp>  
    
    

    Whitespace bringt 95,8% des Originals, Komprimieren 51,1% des Originals, Komprimieren des abgespeckten Codes bringt 51,3% des abgespeckten Codes bzw. 49,1% des Originals. In absoluten Zahlen spart das Entfernen des Whitespace nach dem Komprimieren gerade einmal 77 Bytes ein, unkomprimiert beträgt der Unterschied gerade einmal 164 Bytes.

    Kommentare zu entfernen ist eine ausgesprochen dämliche Idee. Kommentare gehören zum Code, sie erklären minimal außergewöhnliche Stellen. Wenn Du Deinen Code natürlich mit sinnlosen Kommentaren (z.B. close($f); # Datei $f schließen) oder dekorativem Line Noise (z.B. ######################### rund um Funktionen) vollgemüllt hast, macht das Entfernen dieses Mülls den Code nicht nur schlanker, sondern auch wartbarer. Abgesehen davon ist Perl beim Ignorieren von Kommentaren mutmaßlich genauso schnell wie beim Ignorieren von Whitespace.

    POD mitten im Code kann Perl beim Parsen ein wenig bremsen, so dass einige Leute den POD ans Datei-Ende, hinter __END__ verschieben. Der Unterschied ist aber in der Praxis nur selten relevant. Alternativ kann man POD auch in eine separate Datei auslagern. Beides finde ich wenig sinnvoll, denn POD vor jeder einzelnen Funktion bzw. Methode hält Code und Funktionsdokumentation dicht zusammen. Ein paar Promille an Geschwindigkeitseinbußen beim Startup nehme ich dafür gerne in Kauf.

    Erschwerend kommt noch hinzu, dass aggressives Verkleinern des Programmcodes die Zeilennummern und schlimmstenfalls auch Variablen- und Funktionsnamen verändert, so dass es extrem schwierig wird, aus einer Fehlermeldung aus dem verkleinerten Code auf die richtige Stelle im Original-Code zu schließen.

    Alexander

    [1] Ja, s/\s+/ /g ist keine richtige Whitespace-Optimierung. s/\s+/ /g auf Perl-Code angewendet kann den Code demolieren. Allein schon, weil Zeilenenden hinter Kommentaren entfallen. Aber als erste Näherung ist das nicht schlecht.

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".