Menyiapkan sains
Pertama, beberapa skrip untuk membantu kami menguji ini. Ini menghasilkan 2000 file skrip, masing-masing dengan fungsi kecil tunggal:
1..2000 | % { "Function Test$_(`$someArg) { Return `$someArg * $_ }" > "test$_.ps1" }
Itu seharusnya cukup untuk membuat overhead startup normal tidak terlalu penting. Anda dapat menambahkan lebih banyak jika mau. Ini memuat semuanya menggunakan dot-sourcing:
dir test*.ps1 | % {. $_.FullName}
Ini memuat semuanya dengan membaca kontennya terlebih dahulu:
dir test*.ps1 | % {iex (gc $_.FullName -Raw)}
Sekarang kita perlu melakukan beberapa pemeriksaan serius tentang cara kerja PowerShell. Saya suka JetBrains dotPeek untuk dekompiler. Jika Anda pernah mencoba menanamkan PowerShell di aplikasi .NET , Anda akan menemukan bahwa perakitan yang mencakup sebagian besar hal yang relevan adalah System.Management.Automation
. Dekompilasi yang menjadi proyek dan PDB.
Untuk melihat di mana semua waktu misterius ini dihabiskan, kami akan menggunakan profiler. Saya suka yang terintegrasi dengan Visual Studio. Ini sangat mudah digunakan . Tambahkan folder yang berisi PDB ke lokasi simbol . Sekarang, kita bisa melakukan profiling instance dari PowerShell yang hanya menjalankan salah satu skrip pengujian. (Tetapkan parameter baris perintah untuk digunakan -File
dengan path lengkap dari skrip pertama yang akan dicoba. Tetapkan lokasi startup ke folder yang berisi semua skrip kecil.) Setelah itu selesai, buka Properties pada powershell.exe
entri di bawah Target dan ubah argumen untuk menggunakan skrip lainnya. Kemudian klik kanan item paling atas di Performance Explorer dan pilih Mulai Profiling. Profiler berjalan lagi menggunakan skrip lain. Sekarang kita bisa membandingkan. Pastikan Anda mengklik "Tampilkan Semua Kode" jika diberi opsi; bagi saya, itu muncul di area Pemberitahuan di tampilan Ringkasan Laporan Profil Sampel.
Hasilnya masuk
Di komputer saya, Get-Content
versi ini membutuhkan waktu 9 detik untuk membaca 2000 file skrip. Fungsi penting di "Jalur Panas" adalah:
Microsoft.PowerShell.Commands.GetContentCommand.ProcessRecord
Microsoft.PowerShell.Commands.InvokeExpressionCommand.ProcessRecord
Ini sangat masuk akal: kita harus menunggu untuk Get-Content
membaca konten dari disk, dan kita harus menunggu untuk Invoke-Expression
memanfaatkan konten tersebut.
Pada versi dot-source, mesin saya menghabiskan lebih dari 15 detik untuk mengerjakan file-file itu. Kali ini, fungsi di Hot Path adalah metode asli:
WinVerifyTrust
CodeAuthzFullyQualifyFilename
Yang kedua di sana tampaknya tidak berdokumen, tetapi WinVerifyTrust
"melakukan tindakan verifikasi kepercayaan pada objek tertentu." Itu hampir tidak jelas seperti yang Anda dapatkan, tetapi dengan kata lain, fungsi itu memverifikasi keaslian sumber daya yang diberikan menggunakan penyedia yang diberikan. Perhatikan bahwa saya belum mengaktifkan barang keamanan mewah untuk PowerShell, dan kebijakan eksekusi skrip saya adalah Unrestricted
.
Apa itu artinya
Singkatnya, Anda menunggu setiap file untuk diverifikasi dengan suatu cara, mungkin memeriksa tanda tangan, meskipun itu tidak perlu ketika Anda tidak membatasi skrip yang diizinkan untuk dijalankan. Ketika Anda gc
dan kemudian iex
isinya, sepertinya Anda telah mengetik fungsi di konsol, jadi tidak ada sumber daya untuk memverifikasi.