Parallel tree traversal in C#

前端 未结 5 2022
轻奢々
轻奢々 2021-02-05 19:28

I need to traverse a tree quickly, and I would like to do it in parallel. I\'d rather use the parallel extensions than manually spin up a bunch of threads.

My current co

5条回答
  •  时光说笑
    2021-02-05 19:57

    The most direct way would be to create a Task for each child node and then wait for all of them:

    public void Traverse(Node root)
    {
        if (node.Property == someValue)
            DoSomething(node);
    
        var tasks = new List();
    
        foreach (var node in node.Children)
        {
            // tmp is necessary because of the way closures close over loop variables
            var tmp = node;
            tasks.Add(Task.Factory.StartNew(() => Traverse(tmp)));
        }
    
        Task.WaitAll(tasks.ToArray());
    }
    

    Task is fairly light-weight, so creating lots of them works reasonably well. But they do have some overhead, so doing something more complicated like having a few tasks that share a queue is probably going to be faster. If that's the way you're going to go, don't forget that empty queue doesn't mean all work is done. Classes from the System.Collections.Concurrent namespace are going to come handy if you went this way.

    EDIT: Because of the shape of the tree (the root has about 500 children), processing just the first level in parallel should give good performance:

    public void Traverse(Node root, bool parallel = true)
    {
        if (node.Property == someValue)
            DoSomething(node);
    
        if (parallel)
        {
            Parallel.ForEach(node.Children, node =>
            {
                Traverse(node, false);
            });
        }
        else
        {
            foreach (var node in node.Children)
            {
                Traverse(node, false);
            }
        }
    }
    

提交回复
热议问题