开发者

How can I optimize this method?

I would like to optimize the following method, that returns the total file count of the specified folder and all subfolders, for speed and memory usage; any advice is appreciated.

Thanks.

private int countfiles(string srcdir)
{
    try
    {
        DirectoryInfo dir = new DirectoryInfo(srcdir);

        //if the source dir doesn't exist, throw an exception
        if (!dir.Exists)
            throw new ArgumentException("source dir doesn't exist -> " + srcdir);

        int count = dir.GetFiles().Length;

        //loop through each sub directory in the current dir
        foreach (DirectoryInfo subdir in dir.GetDirectories())
        {
            //recursively call this function over and over again
            count += countfiles(subdir.FullName);
        }

        //cleanup
        dir = null;

        return count;
    }
    catch (Exception exc)
    {
        MessageBox.Show(exc.Message);
        return 0;
    }           
}

So I did some benchmark开发者_运维百科ing with the suggestions that were proposed. Here are my findings:

  • My method, with recursion, is the slowest finding 9062 files in a directory tree in 6.234 seconds.

  • @Matthew’s answer, using SearchOption.AllDirectories, is the fastest finding the same 9062 files in 4.546 seconds

  • @Jeffery’s answer, using LINQ, is in the middle of the pack finding the same 9062 files in 5.562 seconds.

Thank you everyone for your suggestions.


Could you not change the entire method to:

int count = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories).Length;


It looks pretty good to me, but I'd use a LINQ expression to get the count.

Try this:

int count = dir.GetFiles().Length + dir.GetDirectories().Sum(subdir =>countfiles(subdir.FullName));

Hope that helps!


I used the approach described here in the past, it shows with and without recursion and the one without is faster. Hope this helps ;-)

How to: Iterate Through a Directory Tree


If there are exceptions, then your user could end up seeing numerous message boxes as each call could show one. I'd consolidate them, allow the user can cancel the operation, or so that it'd back all the way out to the initial caller.


If you are using .NET 4.0, this is slightly faster but not by much.

static int RecurCount(string source)
{
    int count = 0;

    try
    {
        var dirs = Directory.EnumerateDirectories(source);
        count = Directory.EnumerateFiles(source).Count();

        foreach (string dir in dirs)
        {
            count += RecurCount(dir);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

    return count;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜