Wissenschaft aufbauen
Zunächst einige Skripte, die uns dabei helfen, dies zu testen. Dadurch werden 2000 Skriptdateien mit jeweils einer kleinen Funktion erstellt:
1..2000 | % { "Function Test$_(`$someArg) { Return `$someArg * $_ }" > "test$_.ps1" }
Das sollte ausreichen, damit der normale Startaufwand keine Rolle spielt. Sie können bei Bedarf weitere hinzufügen. Dies lädt sie alle mit Dot-Sourcing:
dir test*.ps1 | % {. $_.FullName}
Dies lädt sie alle, indem sie zuerst ihren Inhalt lesen:
dir test*.ps1 | % {iex (gc $_.FullName -Raw)}
Jetzt müssen wir uns genauer ansehen, wie PowerShell funktioniert. Ich mag JetBrains dotPeek für einen Decompiler. Wenn Sie jemals versucht haben, PowerShell in eine .NET-Anwendung einzubetten , werden Sie feststellen, dass die Assembly die meisten relevanten Elemente enthält System.Management.Automation
. Dekompilieren Sie dieses in ein Projekt und einen PDB.
Um zu sehen, wo all diese mysteriöse Zeit verbracht wird, verwenden wir einen Profiler. Ich mag die in Visual Studio integrierte. Es ist sehr einfach zu bedienen . Fügen Sie den Ordner mit dem PDB zu den Symbolpositionen hinzu . Jetzt können wir eine Profilerstellung für eine PowerShell-Instanz durchführen, die nur eines der Testskripts ausführt. (Legen Sie die Befehlszeilenparameter fest, die -File
mit dem vollständigen Pfad des ersten Skripts verwendet werden sollen. Legen Sie den Startpfad auf den Ordner fest, der alle kleinen Skripts enthält.) Öffnen Sie anschließend die Eigenschaften des powershell.exe
Eintrags unter Ziele, und ändern Sie sie die Argumente, um das andere Skript zu verwenden. Klicken Sie dann mit der rechten Maustaste auf das oberste Element im Leistungs-Explorer und wählen Sie Profilerstellung starten. Der Profiler wird erneut mit dem anderen Skript ausgeführt. Jetzt können wir vergleichen. Stellen Sie sicher, dass Sie auf "Show All Code" klicken, wenn die Option angegeben ist. Für mich wird dies in einem Benachrichtigungsbereich in der Zusammenfassungsansicht des Beispielprofilberichts angezeigt.
Die Ergebnisse kommen herein
Auf meinem Computer hat die Get-Content
Version 9 Sekunden gebraucht, um die 2000 Skriptdateien durchzugehen. Die wichtigen Funktionen auf dem "Hot Path" waren:
Microsoft.PowerShell.Commands.GetContentCommand.ProcessRecord
Microsoft.PowerShell.Commands.InvokeExpressionCommand.ProcessRecord
Dies ist sehr sinnvoll: Wir müssen warten, Get-Content
bis der Inhalt von der Festplatte gelesen wurde, und wir müssen warten, bis wir Invoke-Expression
diesen Inhalt nutzen können.
In der Dot-Source-Version brauchte mein Computer etwas mehr als 15 Sekunden, um diese Dateien zu verarbeiten. Diesmal waren die Funktionen auf dem Hot Path native Methoden:
WinVerifyTrust
CodeAuthzFullyQualifyFilename
Die zweite scheint nicht dokumentiert zu sein, WinVerifyTrust
führt jedoch eine Vertrauensüberprüfungsaktion für ein bestimmtes Objekt durch. Das ist ungefähr so vage wie möglich, aber mit anderen Worten, diese Funktion überprüft die Authentizität einer bestimmten Ressource mithilfe eines bestimmten Anbieters. Beachten Sie, dass ich keine ausgefallenen Sicherheitsfunktionen für PowerShell aktiviert habe und meine Skriptausführungsrichtlinie lautet Unrestricted
.
Was das heißt
Kurz gesagt, Sie warten darauf, dass jede Datei auf irgendeine Weise überprüft und möglicherweise auf eine Signatur überprüft wird, obwohl dies nicht erforderlich ist, wenn Sie die ausgeführten Skripts nicht einschränken. Wenn Sie gc
und dann iex
der Inhalt, ist es, als hätten Sie die Funktionen an der Konsole eingegeben, so dass es keine Ressource gibt, die überprüft werden muss.