Chỉ cần một từ để rút ra kết luận (không chính xác) từ bất kỳ lệnh đo lường hiệu suất nào được đề cập trong các câu trả lời. Có một số cạm bẫy cần được xem xét ngoài việc tìm đến thời gian gọi trần của hàm hoặc lệnh (tùy chỉnh).
Sjoemelsoftware
'Sjoemelsoftware' đã bình chọn từ tiếng Hà Lan của năm 2015
Sjoemelen có nghĩa là gian lận, và từ sjoemelsoftware ra đời do vụ bê bối khí thải của Volkswagen. Định nghĩa chính thức là "phần mềm được sử dụng để ảnh hưởng đến kết quả kiểm tra".
Cá nhân, tôi nghĩ rằng " Sjoemelsoftware " không phải lúc nào cũng được cố tình tạo ra để gian lận kết quả kiểm tra mà có thể bắt nguồn từ việc cung cấp tình huống thực tế tương tự như các trường hợp thử nghiệm như dưới đây.
Như một ví dụ, bằng cách sử dụng lệnh đo lường hiệu suất niêm yết, Language Integrated Query (LINQ) (1) , thường có trình độ như các cách nhịn đói để có được một cái gì đó thực hiện và nó thường, nhưng chắc chắn không phải lúc nào! Bất kỳ ai đo tốc độ tăng của hệ số 40 trở lên so với các lệnh PowerShell gốc, có thể đo không chính xác hoặc đưa ra kết luận không chính xác.
Vấn đề là một số lớp .Net (như LINQ) sử dụng đánh giá lười biếng (còn được gọi là thực thi hoãn lại (2) ). Có nghĩa là khi gán một biểu thức cho một biến, nó gần như ngay lập tức được thực hiện nhưng thực tế nó chưa xử lý bất cứ điều gì!
Giả sử rằng bạn chấm nguồn. .\Dosomething.ps1
lệnh của bạn có PowerShell hoặc biểu thức Linq tinh vi hơn (để dễ giải thích, tôi đã nhúng trực tiếp các biểu thức vào Measure-Command
):
$Data = @(1..100000).ForEach{[PSCustomObject]@{Index=$_;Property=(Get-Random)}}
(Measure-Command {
$PowerShell = $Data.Where{$_.Index -eq 12345}
}).totalmilliseconds
864.5237
(Measure-Command {
$Linq = [Linq.Enumerable]::Where($Data, [Func[object,bool]] { param($Item); Return $Item.Index -eq 12345})
}).totalmilliseconds
24.5949
Kết quả có vẻ rõ ràng, lệnh Linq sau này nhanh hơn khoảng 40 lần so với lệnh PowerShell đầu tiên . Thật không may, nó không đơn giản ...
Hãy hiển thị kết quả:
PS C:\> $PowerShell
Index Property
----- --------
12345 104123841
PS C:\> $Linq
Index Property
----- --------
12345 104123841
Như mong đợi, kết quả là như nhau nhưng nếu bạn đã chú ý kỹ, bạn sẽ nhận thấy rằng phải mất nhiều thời gian hơn để hiển thị $Linq
kết quả thì $PowerShell
kết quả.
Chúng ta hãy đo cụ thể rằng chỉ cần lấy một thuộc tính của đối tượng kết quả:
PS C:\> (Measure-Command {$PowerShell.Property}).totalmilliseconds
14.8798
PS C:\> (Measure-Command {$Linq.Property}).totalmilliseconds
1360.9435
Phải mất khoảng 90 yếu tố nữa để lấy một thuộc tính của $Linq
đối tượng sau đó $PowerShell
đối tượng và đó chỉ là một đối tượng!
Cũng lưu ý một cạm bẫy khác là nếu bạn làm lại, một số bước nhất định có thể xuất hiện nhanh hơn rất nhiều trước đó, điều này là do một số biểu thức đã được lưu trữ.
Tóm lại, nếu bạn muốn so sánh hiệu suất giữa hai chức năng, bạn sẽ cần triển khai chúng trong trường hợp đã sử dụng của mình, bắt đầu với phiên PowerShell mới và đưa ra kết luận về hiệu suất thực tế của giải pháp hoàn chỉnh.
(1) Để có thêm thông tin cơ bản và ví dụ về PowerShell và LINQ, tôi khuyên bạn nên sử dụng trang web tihis: PowerShell hiệu suất cao với LINQ
(2) Tôi nghĩ rằng có một sự khác biệt nhỏ giữa hai khái niệm như với đánh giá lười biếng , kết quả được tính khi cần được áp dụng cho thực hiện hoãn lại là kết quả được tính khi hệ thống không hoạt động