Bilim Kurmak
İlk olarak, bunu test etmemize yardımcı olacak bazı komut dosyaları. Bu, her biri tek bir küçük işleve sahip 2000 komut dosyası oluşturur:
1..2000 | % { "Function Test$_(`$someArg) { Return `$someArg * $_ }" > "test$_.ps1" }
Bu, normal başlatma yükünü çok fazla önemli değil yapmak için yeterli olmalıdır. İsterseniz daha fazlasını ekleyebilirsiniz. Bu, nokta kaynağı kullanarak hepsini yükler:
dir test*.ps1 | % {. $_.FullName}
Bu, önce içeriğini okuyarak hepsini yükler:
dir test*.ps1 | % {iex (gc $_.FullName -Raw)}
Şimdi PowerShell'in nasıl çalıştığına dair ciddi bir inceleme yapmamız gerekiyor. Bir decompiler için JetBrains dotPeek seviyorum . PowerShell'i bir .NET uygulamasına gömmeyi denediyseniz , ilgili öğelerin çoğunu içeren derlemenin olduğunu görürsünüz System.Management.Automation
. Bunu bir projeye ve bir PDB'ye dönüştürün.
Tüm bu gizemli zamanın nerede harcandığını görmek için bir profiler kullanacağız. Visual Studio'da yerleşik olanı beğendim. Kullanımı çok kolay . PDB'yi içeren klasörü sembol konumlarına ekleyin . Şimdi, yalnızca test komut dosyalarından birini çalıştıran bir PowerShell örneğinin profil oluşturma işlemini yapabiliriz. (Denenecek -File
ilk komut dosyasının tam yolu ile kullanılacak komut satırı parametrelerini ayarlayın. Başlangıç konumunu tüm küçük komut dosyalarını içeren klasöre ayarlayın.) Bu işlem yapıldıktan sonra, powershell.exe
Hedefler altındaki girişteki Özellikler'i açın ve değiştirin. diğer komut dosyasını kullanmak için argümanlar. Ardından, Performans Gezgini'nde en üstteki öğeyi sağ tıklayın ve Profil Oluşturmaya Başla'yı seçin. Profil oluşturucu diğer komut dosyasını kullanarak yeniden çalışır. Şimdi kıyaslayabiliriz. Seçenek sunulursa "Tüm Kodu Göster" i tıkladığınızdan emin olun; benim için, bu, Örnek Profil Oluşturma Raporunun Özet görünümünde bir Bildirimler alanında görünür.
Sonuçlar gelir
Makinemde, Get-Content
sürümün 2000 komut dosyalarından geçmesi 9 saniye sürdü. "Sıcak Yol" daki önemli fonksiyonlar:
Microsoft.PowerShell.Commands.GetContentCommand.ProcessRecord
Microsoft.PowerShell.Commands.InvokeExpressionCommand.ProcessRecord
Bu çok mantıklı: Get-Content
içeriği diskten okumak için beklememiz Invoke-Expression
ve bu içerikleri kullanmak için beklememiz gerekiyor.
Nokta kaynağı sürümünde, makinem bu dosyalar üzerinde çalışmak için 15 saniyeden biraz fazla zaman harcadı. Bu sefer, Hot Path'daki işlevler yerel yöntemlerdi:
WinVerifyTrust
CodeAuthzFullyQualifyFilename
İkincisi belgelenmemiş gibi görünüyor, ancak WinVerifyTrust
"belirtilen nesne üzerinde bir güven doğrulama eylemi gerçekleştiriyor." Bu, elde edebileceğiniz kadar belirsizdir, ancak başka bir deyişle, bu işlev, belirli bir kaynağın belirli bir sağlayıcıyı kullanarak gerçekliğini doğrular. PowerShell için herhangi bir fantezi güvenlik öğesini etkinleştirmediğimi ve komut dosyası yürütme politikamın olduğunu unutmayın Unrestricted
.
Bu ne demek
Kısacası, çalıştırılmasına izin verilen komut dosyalarını kısıtlamasanız bile, her dosyanın bir şekilde doğrulanmasını, muhtemelen bir imza olup olmadığını kontrol etmeyi bekliyorsunuz. Siz gc
ve daha iex
sonra içindekiler, konsoldaki işlevleri yazmışsınızdır, bu nedenle doğrulanacak kaynak yoktur.