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 -Fileilk 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.exeHedefler 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-Contentsü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-Contentiçeriği diskten okumak için beklememiz Invoke-Expressionve 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 gcve daha iexsonra içindekiler, konsoldaki işlevleri yazmışsınızdır, bu nedenle doğrulanacak kaynak yoktur.