Nếu bạn muốn tránh gọi EnumerateDirectories()
hai lần cho mỗi thư mục, bạn có thể thực hiện nó như vậy:
public IEnumerable<string> EnumerateLeafFolders(string root)
{
bool anySubfolders = false;
foreach (var subfolder in Directory.EnumerateDirectories(root))
{
anySubfolders = true;
foreach (var leafFolder in EnumerateLeafFolders(subfolder))
yield return leafFolder;
}
if (!anySubfolders)
yield return root;
}
tôi đã làm một số xét nghiệm thời gian, và cho tôi phương pháp này là hơn hai lần nhanh như sử dụng phương pháp LINQ.
Tôi đã chạy thử nghiệm này bằng cách sử dụng bản xây dựng bản phát hành, chạy bên ngoài bất kỳ trình gỡ lỗi nào. Tôi chạy nó trên một ổ SSD có chứa một số lượng lớn các thư mục - tổng số thư mục LEAF là 25035.
kết quả của tôi cho chạy thứ hai của chương trình (chạy đầu tiên là để làm nóng bộ nhớ cache đĩa):
Calling Using linq. 1 times took 00:00:08.2707813
Calling Using yield. 1 times took 00:00:03.6457477
Calling Using linq. 1 times took 00:00:08.0668787
Calling Using yield. 1 times took 00:00:03.5960438
Calling Using linq. 1 times took 00:00:08.1501002
Calling Using yield. 1 times took 00:00:03.6589386
Calling Using linq. 1 times took 00:00:08.1325582
Calling Using yield. 1 times took 00:00:03.6563730
Calling Using linq. 1 times took 00:00:07.9994754
Calling Using yield. 1 times took 00:00:03.5616040
Calling Using linq. 1 times took 00:00:08.0803573
Calling Using yield. 1 times took 00:00:03.5892681
Calling Using linq. 1 times took 00:00:08.1216921
Calling Using yield. 1 times took 00:00:03.6571429
Calling Using linq. 1 times took 00:00:08.1437973
Calling Using yield. 1 times took 00:00:03.6606362
Calling Using linq. 1 times took 00:00:08.0058955
Calling Using yield. 1 times took 00:00:03.6477621
Calling Using linq. 1 times took 00:00:08.1084669
Calling Using yield. 1 times took 00:00:03.5875057
Như bạn có thể thấy, sử dụng phương pháp tiếp cận năng suất nhanh hơn đáng kể. (Có lẽ vì nó không liệt kê từng thư mục hai lần.)
mã kiểm tra của tôi:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
namespace Demo
{
class Program
{
private void run()
{
string root = "F:\\TFROOT";
Action test1 =() => leafFolders1(root).Count();
Action test2 =() => leafFolders2(root).Count();
for (int i = 0; i < 10; ++i)
{
test1.TimeThis("Using linq.");
test2.TimeThis("Using yield.");
}
}
static void Main()
{
new Program().run();
}
static IEnumerable<string> leafFolders1(string root)
{
var folderWithoutSubfolder = Directory.EnumerateDirectories(root, "*.*", SearchOption.AllDirectories)
.Where(f => !Directory.EnumerateDirectories(f, "*.*", SearchOption.TopDirectoryOnly).Any());
return folderWithoutSubfolder;
}
static IEnumerable<string> leafFolders2(string root)
{
bool anySubfolders = false;
foreach (var subfolder in Directory.EnumerateDirectories(root))
{
anySubfolders = true;
foreach (var leafFolder in leafFolders2(subfolder))
yield return leafFolder;
}
if (!anySubfolders)
yield return root;
}
}
static class DemoUtil
{
public static void Print(this object self)
{
Console.WriteLine(self);
}
public static void Print(this string self)
{
Console.WriteLine(self);
}
public static void Print<T>(this IEnumerable<T> self)
{
foreach (var item in self)
Console.WriteLine(item);
}
public static void TimeThis(this Action action, string title, int count = 1)
{
var sw = Stopwatch.StartNew();
for (int i = 0; i < count; ++i)
action();
Console.WriteLine("Calling {0} {1} times took {2}", title, count, sw.Elapsed);
}
}
}
Nguồn
2013-07-23 11:57:01
truy cập bình chọn để loại bỏ -1 ... dường như làm việc cho tôi – Sayse
+1, mà chỉ làm cho tôi tự hào ! –
đẹp One-liners – m1m1k