use strict und require
alex
- perl
ahoi,
also ich benutze in meinem skript:
use strict;
require "another.cgi";
allerdings hab ich nun das problem das meine ausgelagerten cgi's,
einen Fehler erzeugen. Ohne dieses use strict kann ich auf meine Variablen in another.cgi zugreifen, was muss ich da also anders machen?
thx, alex
Hi,
allerdings hab ich nun das problem das meine ausgelagerten cgi's,
einen Fehler erzeugen. Ohne dieses use strict kann ich auf meine Variablen in another.cgi zugreifen, was muss ich da also anders machen?
Wie sollen wir dir das sagen, wenn du nicht das eingebundene Script, bzw einen Teil davon, postest?
Grüße Andres Freund
is ganz klein
#!/usr/bin/perl -w
$test="Required";
wenn ich in meinem main cgi file $test aufrufe gibt es n fehler
...
alex
Hi,
allerdings hab ich nun das problem das meine ausgelagerten cgi's,
einen Fehler erzeugen. Ohne dieses use strict kann ich auf meine Variablen in another.cgi zugreifen, was muss ich da also anders machen?
Wie sollen wir dir das sagen, wenn du nicht das eingebundene Script, bzw einen Teil davon, postest?Grüße Andres Freund
Hi,
wenn ich in meinem main cgi file $test aufrufe gibt es n fehler
Was hat das Problem mit cgi zu tuen?
Zu deinem Problem: Gib doch einfach deinem eingebundenen Script nen eigenen Namensraum, ist sowieso besser. Wenn du es dann richtig machst, kannst du es auch mit "use" einbinden, was schneller und mächtiger ist.
Grüße Andres Freund
Hallo,
Wenn du es dann richtig machst, kannst du es auch mit "use" einbinden, was schneller und mächtiger ist.
Schneller kann use afaik nicht sein, da es einerseits das gleiche mahcte wie require und andererseits noch etwas mehr(siehe perldoc -f use).
Grüße
Klaus
Hi,
Hm, ich hatte schon mal geantwortet, ist aber wieder weg.
Schneller kann use afaik nicht sein, da es einerseits das gleiche mahcte wie require und andererseits noch etwas mehr(siehe perldoc -f use).
Ich meine schon das es schneller ist, was sich jetzt gerade mal wieder bestätigt hat. Der Unterschied ist zwar bei meinem kleinen Testscript+Testmodul nicht groß, aber es gibt ihn.
Ich denke das liegt daran, dass der Syntaxprüfer und der Compiler (ja, ich weiß dass manche meinen, dass das so nicht genannt werden darf, aber selbst Larry Wall nennt es so) nicht neu gestartet werden müssen, sondern das ganze in einem Aufwasch durchschauen/kompilieren können. Auch kann der Speicher fpr alle Variablen schon vor der Laufzeit alloziert werden, was nach einer Aussage von Philipp H. gut Rechenzeit einspart.
Grüße Andres Freund
Halihallo Andres
Schneller kann use afaik nicht sein, da es einerseits das gleiche mahcte wie require und andererseits noch etwas mehr(siehe perldoc -f use).
Ich meine schon das es schneller ist, was sich jetzt gerade mal wieder bestätigt hat. Der Unterschied ist zwar bei meinem kleinen Testscript+Testmodul nicht groß, aber es gibt ihn.
Ich denke das liegt daran, dass der Syntaxprüfer und der Compiler (ja, ich weiß dass manche meinen, dass das so nicht genannt werden darf, aber selbst Larry Wall nennt es so) nicht neu gestartet werden müssen, sondern das ganze in einem Aufwasch durchschauen/kompilieren können.
Och, naja, ein Compiler ist Perl schon, nur, dass dieser nicht Maschinencode er-
zeugt, sondern Perl opcodes (sozusagen Maschinencode für die PerlVM). Klar, die
Hauptargumente dagegen sind a) der opcode wird ebenfalls noch "interpretiert" und
b) die Generierung des opcodes geschieht bei jedem Programmstart.
Wie du sagst, darüber kann man Streitgespräche führen, ich denke, dass beide recht und
unrecht haben... Ich sage: auch Maschinencode wird interpretiert, von der CPU nämlich,
warum man einen Unterschied zwischen Softwareinterpretation und Hardwareinterpretation
macht, verstehe ich nicht :-)
Zurück zum Thema: Ich weiss nicht, inwiefern Optimierungen vor/nach BEGIN durchgeführt
werden, oder welchen Einfluss sie auf das Alloziieren von Speicher hat. Ich hoffe, dass
ich das auch im genannten Thread gesagt habe. Ich könnte es mir vorstellen.
Fakt ist:
a) BEGIN/END sind keine normalen Prozeduren und können im Programm-Scope nicht als solche
angesprochen werden (könnten also "speziell" gehandhabt werden).
b) Speicherallozierung ist Zeitaufwändig und wird von Perl wenn möchlich optimiert
(eg. nicht mehr gebrauchte Variablen-Speicher (AV,SV,IV,HV,..) werden wiederverwendet)
was ich glaube ist:
a) Opcode-Optimizer startet vorher und somit wäre da der Zeitpunkt, wo Speicher
für die PerlVM alloziiert wird (später wird Speicher durch perlinterne Makros
verwaltet, falls Perl so kompiliert wurde, ggf. muss neuer Speicher vom OS
geholt werden).
b) Wenn also bereits Module beim Startup eingelesen werden, könnten Variablen im
Modul-Scope eigentlich beim Opcode-Optimizer erkannt werden und den Speicheraufwand
beeinflussen (den virtuellen Speicher zu der PerlVM zu begin festlegen, sodass der
Speicher nicht mehr zur Laufzeit vom OS angefordert werden muss und alles in einem
Block alloziiert wird).
Inwieweit, oder gar überhaupt, Optimierungen für BEGIN-Blöcke ausgeführt werden, weiss
ich leider nicht, wie gesagt, ich könnte es mir vorstellen.
Hast du wirklich Benchmarks ausgeführt und konntest du feststellen, dass use schneller
ist als require? - Denn Klaus'es Argumentation, dass use genau das macht, wie require
und noch ein bischen mehr, ist wahr. Zudem misst man beim Benchmark in dieser
mikroskopischen Welt wohl eher die Zeit des Betriebssystems die eventuell gecachte
Moduldatei auszulesen, als das Alloziieren von Speicher durch Perl, denn letzteres
geht im Vergleich doch rasant schnell... Ein Benchmarking auf dieser low-level-Ebene ist
mit leider grosser Vorsicht zu geniessen.
Viele Grüsse
Philipp
Halihallo zusammen
Zurück zum Thema: Ich weiss nicht, inwiefern Optimierungen vor/nach BEGIN durchgeführt
werden, oder welchen Einfluss sie auf das Alloziieren von Speicher hat. Ich hoffe, dass
ich das auch im genannten Thread gesagt habe. Ich könnte es mir vorstellen.
Fakt ist:
a) BEGIN/END sind keine normalen Prozeduren und können im Programm-Scope nicht als solche
angesprochen werden (könnten also "speziell" gehandhabt werden).
b) Speicherallozierung ist Zeitaufwändig und wird von Perl wenn möchlich optimiert
(eg. nicht mehr gebrauchte Variablen-Speicher (AV,SV,IV,HV,..) werden wiederverwendet)
was ich glaube ist:
a) Opcode-Optimizer startet vorher und somit wäre da der Zeitpunkt, wo Speicher
für die PerlVM alloziiert wird (später wird Speicher durch perlinterne Makros
verwaltet, falls Perl so kompiliert wurde, ggf. muss neuer Speicher vom OS
geholt werden).
b) Wenn also bereits Module beim Startup eingelesen werden, könnten Variablen im
Modul-Scope eigentlich beim Opcode-Optimizer erkannt werden und den Speicheraufwand
beeinflussen (den virtuellen Speicher zu der PerlVM zu begin festlegen, sodass der
Speicher nicht mehr zur Laufzeit vom OS angefordert werden muss und alles in einem
Block alloziiert wird).
Sorry, ich rede einfach gerne über die Internals und Denke auch gerne darüber nach: ;)
nehmen wir ein kleines Script:
--
use strict;
our $test1= 'Philipp Hasenfratz';
our $test2= 'Hauptstrasse 3';
our $test3= '8259 Wagenhausen';
while ( my ($n,$v) = each %{main::} ) {
print "$n => $v\n"
}
--
Wie man sieht, stehen die drei Variablen (und weitere) in der symbol-table des Moduls
main. Was, wenn wir ein Programm mit 10'000 Variablen hätten? - Beim optimizer wären
diese bereits sichtbar und es wäre wohl sehr performant, wenn gleich für alle Variablen
Speicher im "Packet" angefordert werden würde, ansonsten müsste Perl ca. 20'000
Memory-allocations durchführen, für Variablen, die evtl. nur 10 Bytes beanspruchen...
Ein alloziieren von 20'000 * 10 Bytes[1], also 200'000 Bytes wäre sehr viel schneller.
Was, wenn Module über 'use' eingebunden werden? - Der Parser lädt die Module ein, nachher
springt der Opcode-Optimizer an; dieser könnte nun die sym-table analysieren und den
minimalen Speicheraufwand errechnen und diesen gleich in einem Packet alloziieren.
Dann sollte man gleich noch einige KB's für Laufzeitvariablen alloziieren, denn die
VM's schmeissen mit Variablen rum, wie George W. mit Gewehrpatronen. Eine Optimierung
macht hier, wie ich denke, schon Sinn, aber leider sind Block-Scoped-Variablen (also
z. B. solche, die in einer Prozedur mit 'my' definiert werden) sehr viel verbreiteter
und diese können eben nicht im Startup erkannt werden, da sie eben erst zur Laufzeit
in den "Scope geraten" (iniziiert, geändert, zerstört).
Inwiefern - oder überhaupt - dies jedoch in Perl geschieht, weiss ich wie gesagt nicht,
leider, würde mich nämlich interessieren. Wie Perl mit den Variablen hantiert und was es
mit dem virtuellen Speicher von Perl auf sich hat, ist mir schon bekannt, aber ich kenne
die Optimierungen nicht.
Weiss vielleicht jemand geeignete Lektüre?
[1] Die Rechnung wiedergibt nicht die Realität, sondern dient nur dem Verständnis, in
Wahrheit müssten noch weitaus mehr alloc's durchgeführt werden.
Viele Grüsse
Philipp
Halihallo nochmals ;)
Zur Vollständigkeit noch den "alten" Thread, den Andres IMHO anspricht:
http://forum.de.selfhtml.org/archiv/2003/1/34581/#m188507
Viele Grüsse
Philipp
Hi,
Ich meine schon das es schneller ist, was sich jetzt gerade mal wieder bestätigt hat. Der Unterschied ist zwar bei meinem kleinen Testscript+Testmodul nicht groß, aber es gibt ihn.
So ich hab jetzt nochmal getestet, mit Modulen sinnvoller Größe.
Zwei Scripte haben jeweils die Module DBI und CGI eingebunde, da diese beiden Recht groß sind, nur werden die Module beim einen mittels require eingebunden und beim anderen mittels use. Sonst sind diese Scripte leer.
Nun habe ich diese Scripte mittels eines dritten Scriptes und System immer wieder ausführen lassen. Damit ich einigermaßen sinnvolle nicht durch irgendwelche anderen Prozesse gestörten Ergebnisse bekomme, habe ich einmal 50000 Wiederholungen ausgewählt.
Das Script mir require war in der gesamten Zeit um Zeit um ungefähr 3 Sekunden, bei einer Messgenauigkeit von 1 Sekunde, schneller. Da das ganze ungefähr 15 Minuten gedauert hat, ist diese Zeit zu vernachlässigen, aber ich habe das selbe Ergebnis bei Drei durchläufen erhalten.
Nun habe ich die beiden Testscripte noch mit damit belästigt, dass sie einen Regex und eine Dateiöffnung plus schreiben ausführen durften. Sonst der gleiche Aufbau.
Siehe da, auf einmal war das Script mir use um 30 Sekunden schneller.
Bei beiden "Versuchen" war nicht die CPU, sondern der Ram das knappe Gut, wobei mit 150 freien MB auch relativ wenig zur verfügung stand.
Dass bei der 2. Version des Testes die version mit use langsamer war, liegt _denke_ ich daran, dass durch den erneuten Aufruf des Compilers während der Laufzeit mehr Memory verbraucht wurde, so dass weniger für den Regex und Co zur Verfügung standen.
Grüße Andres Freund
Hi alex,
allerdings hab ich nun das problem das meine ausgelagerten cgi's,
einen Fehler erzeugen.
welchen?
Ohne dieses use strict kann ich auf meine Variablen in another.cgi zugreifen,
Vielleicht.
In jedem Falle machst Du etwas 'falsch' - und schaltest noch dazu die Warnvorrichtung, welche Dich auf diesen Fehler hinweisen will, ab.
Würdest Du in Deinem Auto ein blinkendes Warnlicht auch einfach abschalten wollen?
was muss ich da also anders machen?
Verstehe die Fehlermeldung und behebe den Fehler.
Viele Grüße
Michael
Hi alex,
Solange "use strict" benutzt wird, dann muessen die Variablen
mit "my" davor deklariert sein. Also statt:
$test;
muss so sein
my $test;
Viel Erfolg
x-VieW