Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Skripte ausführen

Der Befehl pperl von PetaPerl führt Perl-Skripte mit einer vertrauten Schnittstelle aus. Die meisten perl5-Optionen funktionieren identisch.

Grundlegende Ausführung

# Skript ausführen
pperl script.pl

# Mit Argumenten ausführen
pperl script.pl arg1 arg2

# Einzeiler ausführen
pperl -e 'say "Hello, World!"'

# Nur Syntax prüfen, ohne auszuführen
pperl -c script.pl

Kommandozeilenoptionen

Perl-kompatible Optionen

OptionBeschreibungBeispiel
-e 'code'Einzeiler ausführen (moderne Features immer aktiv)pperl -e 'say "hi"'
-cNur Syntax prüfenpperl -c script.pl
-wWarnungen aktivierenpperl -w script.pl
-vVersion anzeigenpperl -v
-VAusführliche Konfigurationpperl -V
-h, -?, --helpHilfe anzeigenpperl --help

Kombinierte Kurzoptionen:

pperl -wc script.pl  # Warnungen aktivieren + Syntaxprüfung

PetaPerl-spezifische Optionen

OptionBeschreibungStandard
--stats, -sLeistungsstatistiken anzeigen (Zeit, Speicher, Ops)Deaktiviert
--trace, -tAusführungsverfolgung aktivierenDeaktiviert
--timeout=SECSZeitlimit für Ausführung in SekundenKeines
--p5P5-Laufzeit verwenden (siehe unten)Deaktiviert

Auswahl der Laufzeitumgebung

PetaPerl verfügt über zwei Laufzeitumgebungen. Die standardmäßige PP-Laufzeit verwendet sicheres, idiomatisches Rust und unterstützt JIT-Kompilierung sowie Auto-Parallelisierung. Die P5-Laufzeit (--p5) ist eine zeilengetreue Rust-Übertragung des C-Interpreters von perl5 — sie erreicht unmittelbar perl5-Leistung, unterstützt aber weder JIT noch Parallelisierung.

--p5 eignet sich, wenn maximale Kompatibilität mit dem Randverhalten von perl5 oder Basisleistung ohne JIT benötigt wird. Die Standard-PP-Laufzeit (mit aktiviertem JIT) eignet sich für rechenintensive Aufgaben, bei denen Parallelisierung und JIT deutliche Geschwindigkeitsvorteile bringen.

Leistungsoptionen

OptionBeschreibungStandard
--no-jitJIT-Kompilierung deaktivierenJIT aktiviert
--no-parallelAuto-Parallelisierung deaktivierenParallelisierung aktiv
--threads=NAnzahl der Threads für ParallelisierungAlle CPUs
--parallel-threshold=NMinimale Iterationen für Parallelisierung100

Caching- und Analyseoptionen

OptionBeschreibung
--cacheBytecode-Caching aktivieren (~/.pperl/cache/)
--flushAlle Bytecode-Caches leeren und beenden
--dump-optreeKanonischen Op-Tree ausgeben (nicht ausführen)
--from-json, -jOp-Tree von stdin lesen (B::PetaPerl-JSON-Format)
--optree, -oOp-Tree von stdin lesen (B::Concise-Format)
--compare-bytecodeOp-Trees vergleichen: perl5-Backend vs. nativer Parser

Nicht unterstützte perl5-Optionen

Folgende perl5-Flags sind nicht implementiert:

OptionBeschreibungUmgehung
-IInclude-Pfad hinzufügenPERL5LIB verwenden
-EMit Features ausführen-e verwenden (Features immer aktiv)
-M / -mModul ladenuse im Code verwenden
-n / -pImplizite EingabeschleifeExplizite Schleife schreiben
-lAutomatisches Zeilenendechomp/say verwenden
-a / -FAutosplitsplit explizit verwenden
-iIn-Place-Bearbeitungopen/close verwenden
-dDebugger-
-xSkript extrahieren-
-TTaint-Modus-

Beispiele

Einzeiler

Moderne Features (say, state usw.) sind immer aktiviert.

# Hallo ausgeben
pperl -e 'say "Hello!"'

# Eingabe verarbeiten
echo "hello" | pperl -e 'while (<>) { say uc($_) }'

# Rechnen
pperl -e 'say 2 + 2'

# Daten erzeugen
pperl -e 'say join ",", 1..10'

Syntaxprüfung

# Einzelne Datei prüfen
pperl -c script.pl
# Ausgabe: script.pl syntax OK

# Mit aktivierten Warnungen prüfen
pperl -wc script.pl

Skript-Argumente

Argumente nach dem Skriptnamen befüllen @ARGV.

pperl process.pl file1.txt file2.txt
# process.pl
for my $file (@ARGV) {
    say "Processing: $file";
}

Leistungsstatistiken

pperl --stats script.pl

Ausgabe:

--- Performance Statistics ---
Wall-clock time: 0.042 seconds
Peak memory (RSS): 12.34 MB (12640 KB)
Ops executed: 1523 (36261 ops/sec)
------------------------------

Ausführungsverfolgung

Jede ausgeführte Op wird angezeigt (Hilfsmittel zur Fehlersuche).

pperl --trace script.pl

Ausgabe:

[TRACE] NextState
[TRACE] Const("Hello")
[TRACE] Print

Parser-Vergleich

Ausgabe des nativen Rust-Parsers mit einem von perl5 erzeugten JSON-Op-Tree vergleichen (Analysewerkzeug).

pperl --compare-bytecode script.pl

Zeigt Unterschiede in den erzeugten Op-Trees. Nützlich zur Parser-Validierung.

Op-Tree-Inspektion

Kanonische Op-Tree-Darstellung ausgeben, ohne auszuführen.

pperl --dump-optree script.pl

Zeigt die interne Op-Tree-Struktur:

NextState(file="script.pl", line=1)
  → Const(sv="Hello")
    → Print
      → LeaveSub

Ausführungsmodell

Parser-Pipeline

Quellcode → Lexer → Parser → AST → Codegen → OpArena → Interpreter

Schnell, reines Rust. Keine perl5-Abhängigkeit zur Laufzeit.

JSON-Op-Tree-Laden (nur Analyse)

Quellcode → perl + B::PetaPerl → JSON → OpArena → Interpreter

Für Analyse und Parser-Validierung kann pperl einen von perl5 erzeugten Op-Tree über --from-json laden oder ihn über --compare-bytecode mit dem nativen Parser vergleichen. Dies wird bei normaler Ausführung nicht verwendet.

Zeitlimits

Standardmäßig hat pperl kein Zeitlimit. Mit --timeout=SECS kann eines gesetzt werden:

# Kein Zeitlimit (Standard)
pperl script.pl

# Zeitlimit setzen (nützlich für nicht vertrauenswürdigen Code oder Tests)
pperl --timeout=60 script.pl
pperl --timeout=5 script.pl

Das Test-Harness setzt ein eigenes Zeitlimit (standardmäßig 5 Sekunden pro Test). Dieses ist unabhängig vom --timeout-Flag.

Exit-Codes

CodeBedeutung
0Erfolg
1Laufzeitfehler oder Kompilierfehler
2Fehler bei Kommandozeilenverwendung

Umgebungsvariablen

VariableWirkungStandard
PPERL_MAX_RECURSIONMaximale Rekursionstiefe für Subroutinen1000
PPERL_CACHEVerzeichnis für Bytecode-Cache-
PERL5LIBModul-Suchpfad-

Beispiel:

export PPERL_MAX_RECURSION=5000
pperl deeply_recursive.pl

export PPERL_CACHE=/tmp/pperl-cache
pperl --cache script.pl

Warnungen

Warnungen mit -w oder -W aktivieren:

pperl -w script.pl

Warnungen erscheinen auf stderr. Derzeit implementiert:

  • Verwendung eines nicht initialisierten Werts
  • Aufruf einer undefinierten Subroutine

Standardströme

# stdin lesen
while (my $line = <STDIN>) {
    print "Got: $line";
}

# stdout schreiben
print "Output\n";
say "Output with newline";

# stderr schreiben
warn "Warning message\n";

Umleitung funktioniert wie gewohnt:

pperl script.pl < input.txt > output.txt 2> errors.txt

Shebang-Unterstützung

PetaPerl-Skripte unterstützen Shebang für direkte Ausführung.

#!/usr/bin/env pperl
say "Hello from PetaPerl!";

Ausführbar machen und starten:

chmod +x script.pl
./script.pl

Modulladen

use strict;
use warnings;
use Data::Dumper;

my $data = { foo => 42 };
print Dumper($data);

Modul-Suchpfad: identisch mit perl5s @INC. Mit PERL5LIB können Verzeichnisse hinzugefügt werden.

Aktuelle Einschränkungen:

  • XS-Module nicht unterstützt (nur native Module)
  • Einige Pragmas (strict, warnings) werden geparst, aber nicht vollständig durchgesetzt
  • Pure-Perl-Module funktionieren, sofern sie keine nicht unterstützten Features verwenden

Unterschiede zu perl5

Immer aktivierte Features

Moderne Perl-Features sind immer verfügbar (kein use feature nötig):

  • say - Ausgabe mit Zeilenumbruch
  • state - persistente lexikalische Variablen
  • // - Defined-Or-Operator
  • ~~ - Smart Match (teilweise)

Standard-Zeitlimit

pperl hat kein Standard-Zeitlimit (wie perl5). Mit --timeout=SECS kann für nicht vertrauenswürdige Skripte eines gesetzt werden.

Parser

pperl verwendet immer den nativen Rust-Parser. Es gibt keinen Laufzeit-Fallback auf perl5.

Fehlersuche

Syntaxfehler

pperl -c script.pl

Meldet Parse-Fehler mit Zeilennummern:

Parse error: Expected ';' after statement
  at script.pl line 42

Laufzeitfehler

Fehler zeigen einen Stacktrace:

Runtime error: Undefined subroutine &main::foo
  called at script.pl line 10

Ausführungsverfolgung

pperl --trace script.pl

Zeigt jede ausgeführte Op. Sehr ausführlich. Nützlich zum Verständnis des Ausführungsablaufs.

Leistungstipps

Benchmarking

time pperl script.pl

Oder --stats für detaillierte Metriken:

pperl --stats script.pl

Leistungscharakteristiken

Die Leistung von PetaPerl variiert je nach Arbeitslast:

  • Interpreter-Fast-Paths: Häufige Operationen (Ganzzahlarithmetik, Zuweisung, Vergleich) laufen mit oder nahe perl5-Geschwindigkeit
  • JIT-kompilierte Schleifen: Arithmetik-intensive Schleifen werden über Cranelift zu nativem Code kompiliert und erreichen bis zu 76-fache perl5-Geschwindigkeit
  • JIT + Parallelisierung: Trivial parallelisierbare Aufgaben auf Mehrkern-Systemen erreichen bis zu 431-fache perl5-Geschwindigkeit (Mandelbrot 1000x1000)
  • String-intensiver Code: Vergleichbar mit perl5 dank PvBuf-Optimierungen
  • Modulladen: Ähnlich wie perl5 für Pure-Perl-Module

Mit --no-jit und --no-parallel kann die reine Interpreter-Leistung isoliert werden.

Übliche Arbeitsabläufe

Skript-Entwicklung

# Skript bearbeiten
vim script.pl

# Syntax prüfen
pperl -c script.pl

# Mit Warnungen ausführen
pperl -w script.pl

# Bei Bedarf mit Tracing debuggen
pperl --trace script.pl

Testen

# Syntax aller Skripte prüfen
find . -name '*.pl' -exec pperl -c {} \;

# Testsuite ausführen
pperl t/test.pl

Produktiv-Einsatz

# Produktionsskript ausführen (kein Zeitlimit standardmäßig)
pperl production.pl

# Leistung überwachen
pperl --stats production.pl

Fortgeschrittene Verwendung

Op-Tree aus JSON laden (Analyse)

Für Parser-Validierung und Analyse:

# JSON-Format (B::PetaPerl) — liest von stdin
perl -MO=PetaPerl script.pl | pperl --from-json

# Kurzform
perl -MO=PetaPerl script.pl | pperl -j

Dies lädt einen von perl5 erzeugten Op-Tree und führt ihn in der PetaPerl-Laufzeit aus, wobei der native Parser umgangen wird.

Parser vergleichen

Ausgabe des nativen Parsers mit einem von perl5 erzeugten Op-Tree vergleichen:

pperl --compare-bytecode script.pl

Zeigt strukturelle Unterschiede. Exit-Code 0 = äquivalent, 1 = verschieden.

Fehlerbehebung

“Can’t open perl script”

Datei existiert nicht oder falscher Pfad.

pperl script.pl  # Muss existieren

“Undefined subroutine”

Subroutine nicht definiert oder im aktuellen Gültigkeitsbereich nicht sichtbar.

sub greet { say "hi" }
greet();  # OK

greeet();  # Fehler: Undefined subroutine

“Timeout expired”

Das Skript lief länger als der --timeout-Wert.

pperl --timeout=120 long_script.pl  # Zeitlimit erhöhen
pperl long_script.pl                # Kein Zeitlimit (Standard)

“Parse error”

Syntaxfehler im Skript. Mit -c prüfen:

pperl -c script.pl

“Is perl installed and in PATH?”

Die Analysewerkzeuge --from-json/-j und --compare-bytecode erfordern ein installiertes perl 5.42+ mit B::PetaPerl. Normale Ausführung benötigt kein perl.

Versionsinformationen

pperl -v

Zeigt Kurzversion und Copyright.

pperl -V

Zeigt ausführliche Konfiguration:

Summary of PetaPerl configuration:

  PetaPerl:
    version='0.1.0'
    binary='pperl'

  Runtime:
    backend=Rust interpreter + function-pointer dispatch
    jit=Cranelift (for/while loops)
    parallelism=Rayon (auto-parallel map/grep/for/while)

  Perl compatibility:
    parser=native Rust
    perl_required=no (5.42+ optional for --from-json/--compare-bytecode analysis)
    platforms=Linux only

Plattform-Unterstützung

PetaPerl läuft ausschließlich unter Linux (jede Architektur).

Nicht unterstützt: Windows, macOS, BSD, VMS usw.

Diese Vereinfachung ermöglicht aggressive Optimierung für Linux-spezifische Funktionen.

Geplante Erweiterungen

Geplante Features:

  • Profiling-Ausgabe (--profile)
  • Erweiterte JIT-Abdeckung (String-Operationen, Subroutine-Inlining)
  • Erweiterte Parallelisierung (weitere Schleifenmuster, Pipeline-Parallelismus)

Fortschritt verfolgen: https://gl.petatech.eu/petatech/peta-perl