Câu hỏi Tại sao Powershell quá chậm?


Tôi đã cố gắng thực hiện một điều đơn giản với PowerShell, tìm các tệp chiếm nhiều dung lượng nhất trên ổ đĩa. Tôi đã sử dụng ls + sort và ... nó đã mãi mãi cho tôi.

Đôi khi tôi sử dụng quản lý xa và so sánh với PowerShell, nó trông nhanh hơn và ổn định hơn nhiều.

Ok, nó dựa trên .NET, nhưng .NET không quá chậm. Tôi mong đợi để xem một cái gì đó nhẹ và nhanh chóng! Đó là giao diện điều khiển!

Một điều nữa, tôi muốn có một cái gì đó như IEnumerable trong PowerShell để xem kết quả ngay lập tức. Có thể đạt được không? Nó có thể giúp một chút trong khi chờ đợi kết quả gây ra đôi khi tôi nghĩ rằng nó chỉ đi chơi.

CHỈNH SỬA

Tôi đang làm một cái gì đó như thế

ls -Recurse -ErrorAction SilentlyContinue | sort -Property Size | select -First 10

Và tôi đoán nó có thể mất DAYS.

CHỈNH SỬA

Chỉ để so sánh.

Mã C # mất khoảng 2 phút. Để chắc chắn nó không phải là lý tưởng và không xử lý tất cả các tập tin, nhưng nó xử lý ít nhất> 95%.

void Main()
{
    GetFilesSize(@"C:\").OrderByDescending(x => x).Take(10).ToList();
}

public IEnumerable<long> GetFilesSize(string directory)
{
    var accessDenied = false;
    var dirList = new string[0]; 
    try
    {
        dirList = Directory.GetDirectories(directory);
    }
    catch{
        accessDenied = true;
    }

    if(accessDenied) yield break;

    foreach (var dir in dirList)
    {
        foreach (var size in GetFilesSize(dir))
        {
            yield return size;
        }
    }

    foreach (var fileName in Directory.GetFiles(directory))
    {
        if(fileName.Length>=260) continue;
        yield return new FileInfo(fileName).Length;
    }
}

4
2018-05-13 01:47


gốc


"Một điều nữa ..." Không, làm ơn, không! Đừng hỏi câu hỏi thứ hai, câu hỏi này sẽ tạo ra các câu trả lời bổ sung / khác biệt / không liên quan, trong cùng một câu hỏi. Chỉ cần tạo một câu hỏi SuperUser mới. - TOOGAM
sẽ rất hữu ích để xem mã của bạn "chậm quá" vì có lẽ nó không phải PowerShell chậm, thay vì mã của bạn! - SimonS
Chào mừng bạn đến Siêu người dùng! Vui lòng thử và hỏi 1 câu hỏi cùng một lúc (nếu không câu hỏi của bạn sẽ bị đóng quá rộng). - DavidPostill♦
@Ramhound Nếu bạn đọc ý kiến ​​của tôi cẩn thận, bạn có thể thấy rằng tôi phàn nàn về hiệu suất của powerhell, chứ không phải .net. .NET được đề cập là cơ sở của PowerShell hoạt động nhanh hơn. Không chắc về tổng số tệp, tôi đang cố quét toàn bộ ổ đĩa. Vì vậy, tôi đoán có hàng ngàn tệp. - Neir0
@Ramhound Tôi đã tính: 556458 - Neir0


Các câu trả lời:


PowerShell là một chương trình được viết bằng .Net, nhưng nó sử dụng các giao diện cho nhiều trình thông dịch và thời gian chạy khác nhau khi nó thực sự đang chạy. Đó là một Shell, vì vậy giống như BASH, mặc dù nó được viết bằng C, nhưng không nói gì về các tập tin nhị phân và tập lệnh được thực hiện bên trong nó. Thực thi có thể là mã .Net, lệnh VDM / CMD, lệnh * nix shell, VB / C / WSScript, WMI invocations, giao diện API không được quản lý, tệp jar hoặc bất kỳ thứ gì khác. Những lựa chọn này là những gì ảnh hưởng đến hiệu năng của mã đang chạy bên trong trình bao, chứ không phải ngôn ngữ mà trình bao được viết.

Bây giờ, có vẻ như bạn đang gặp khó khăn với việc thực hiện một lệnh cụ thể. Vì vậy, câu hỏi hay hơn là, tại sao ls chậm sắp xếp khi được gọi từ trong PowerShell. Khi chúng tôi đào sâu hơn, chúng tôi thấy rằng ls là một bí danh cho 'Get-ChildItem' trả về một mảng đối tượng chứa các đối tượng System.IO.DirectoryInfo.

PS C:\Windows\system32> $x=Get-ChildItem ./
PS C:\Windows\system32> $x.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array 

PS C:\Windows\system32> $x[1].GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     DirectoryInfo                            System.IO.FileSystemInfo   

PS C:\Windows\system32>

Bạn có thể truy xuất ls và sau đó đưa nó vào Sort-Object  gọi điện và nó sẽ hoạt động chủ yếu theo cách mà IEnumerable thực hiện.

Lưu ý rằng IEnumerable không làm bất cứ điều gì cho hiệu suất. Bạn có thể nhầm lẫn nó với IQueryable, định nghĩa nhưng không thực hiện truy vấn cho đến giây cuối cùng, có lẽ sau khi nó được trang trí với các hoạt động lọc và sắp xếp, theo cách .Net thực hiện thông qua LINQ to Objects. Trong trường hợp này, vì Get-ChildItem không cung cấp công cụ truy vấn được tối ưu hóa hoặc nguồn dữ liệu được lập chỉ mục, bạn thực sự không thể so sánh các hoạt động cơ sở dữ liệu hiện đại với các danh sách thư mục.

Vì vậy, cuối cùng, hãy thử một cái gì đó như: ls ./ -recurse | Sort-Object Name -descending Đối với tôi, nhắm mục tiêu System32, điều này mất khoảng 20 giây để xử lý và sắp xếp 54430 tệp.

Cuối cùng, lưu ý rằng bạn sẽ có hiệu suất lớn khi bạn cố gắng liệt kê một thư mục mà bạn không có quyền truy cập, vì vậy hãy đảm bảo bạn không đệ quy vào những nơi bạn không được phép đi hoặc bạn sẽ phải chịu đựng 2 + thứ hai chờ đợi cho mỗi.

Hy vọng rằng sẽ giúp.


10
2018-05-13 22:26



IEnumerable không cho hiệu suất đạt được nhưng cho phép xem kết quả ngay lập tức. Cũng trong trường hợp của PowerShell nó có thể cải thiện hiệu suất rất nhiều nguyên nhân ví dụ nếu "ls" trở lại IEnumerable nó không tải tất cả các cây tập tin vào bộ nhớ những gì có thể là một chi phí lớn. - Neir0
Tôi đã thử ls + sắp xếp như bạn đã đề cập trong bài đăng của mình, tôi muốn kiểm tra tất cả các tệp trên ổ đĩa nhưng chắc chắn không thể thực hiện hoặc tôi đoán có thể mất vài ngày (thực sự, vì tôi đã để nó vào ban đêm và tại buổi sáng không có kết quả nào). Nhưng ví dụ nếu tôi sẽ lấy những cái utils đặc biệt để kiểm tra dung lượng ổ đĩa, chúng hoạt động rất nhanh. Đó là quan điểm của tôi. Mọi thứ, di chuyển, sao chép, tìm kiếm hoạt động chậm trong PowerShell và nó là gây phiền nhiễu. - Neir0
thử chuyển hướng đầu ra sang một tệp. một đĩa âm lượng tiêu chuẩn không nên mất cả đêm để liệt kê. bạn đã ở giới hạn trên RAM hay đĩa không lành mạnh? - Frank Thomas
Không chắc chắn, có lẽ đã xảy ra sự cố với ổ đĩa, tôi cần thực hiện các kiểm tra bổ sung. Tôi có một công cụ khác (TreeSize) hoạt động khá nhanh, vì vậy nó không quá rõ ràng. - Neir0


PowerShell được xây dựng để thuận tiện hơn là nhanh. Đó là một sự cân bằng - nó hoạt động sau hậu trường, vì vậy người dùng phải làm ít hơn. Làm nhiều công việc hơn làm chậm hơn.

Hãy xem mã PowerShell của bạn là một dòng, để thực hiện nhiều hơn mã C # của bạn trong 15 dòng.

Nó làm nhiều hơn - mặc dù bạn không sử dụng nó.

ls trên Linux trả về chuỗi, chuỗi đơn giản và nhanh chóng. Mã .Net của bạn thậm chí không giữ tên tệp mà nó chỉ giữ kích thước và các số nhỏ hơn một lần nữa vì vậy đó là thậm chí nhanh hơn.

ls trong PowerShell, trả về các đối tượng [FileInfo] và [DirectoryInfo] - mỗi đối tượng phải được tạo và mỗi tệp phải truy vấn tệp để điền vào các trường khác như CreationTime và LastWriteTime và Extension và Length và các trường thời gian phải tạo Các đối tượng [DateTime].

Đó là rất nhiều chậm hơn cho mỗi tập tin. Chi phí để kích hoạt các tùy chọn khác, ngay cả khi bạn không sử dụng chúng - mã PowerShell của bạn có thể thay đổi để lấy kích thước của 10 tệp đầu tiên được tạo vào tháng 1 với một thay đổi đơn giản, không có các lệnh hoặc công cụ khác, và vẫn là một dòng, mã C # sẽ phải được viết lại rộng rãi, truy vấn thời gian tạo, mang cả thời gian và kích thước tạo ra cho sắp xếp, v.v.

Lý do bạn không thấy kết quả ngay lập tức là vì bạn | sort. Điều đó làm cho nó không thể. Điều gì sẽ xảy ra nếu bạn bắt đầu xuất kết quả ngay lập tức nhưng tệp cuối cùng được tìm thấy cần phải sắp xếp về phía trước? Sau đó, đầu ra sẽ sai - IEnumerable không thể làm gì về điều này, | sort phải thu thập mọi đầu vào trước khi nó có thể xuất ra bất cứ thứ gì. Sắp xếp của bạn nhanh hơn vì sắp xếp những thứ nhỏ

Mã .Net của bạn có thể tự phân loại nhanh hơn vì nó sắp xếp một số lượng [long], nó không phải thực hiện bất kỳ tra cứu đặc tính nào.

Nói chung, mã của bạn ít hơn rất nhiều và việc làm ít tốn ít thời gian hơn. Nhưng bạn mất nhiều thời gian để viết và ít linh hoạt hơn và tập trung hơn. Một sự cân bằng.


2
2017-09-23 21:40