需要让我的递归函数运行得更快

发布于 2024-10-31 09:52:13 字数 2850 浏览 0 评论 0原文

这是导致我“问题”的代码:

private string buildHTMLTree()
{
    Dictionary<string, string> parents = new Dictionary<string, string>();
    Dictionary<string, string> childs = new Dictionary<string, string>();
    ArrayList array = new ArrayList();
    array = simulateInput();

    string html = "";

    foreach (KeywordRows kwd in array)
    {
        if (kwd.root_keyword == kwd.keyword)
        {
            if (!parents.ContainsKey(kwd.keyword))
                parents.Add(kwd.keyword, kwd.root_keyword);
        }
        else
        {
            if (!childs.ContainsKey(kwd.keyword))
                childs.Add(kwd.keyword, kwd.root_keyword);
        }
    }

    html += "<ul id=\"parents\">";
    foreach (string parent in parents.Values)
    {
        html += "<li id=\"" + parent + "\">" + parent;

        if (childs.ContainsValue(parent))
        {
            html += "<ul id=\"parents\">";
            process(ref childs, ref html, parent);
            html += "</ul>";
        }

        html += "</li>";
    }
    html += "</ul>";

    return Properties.Resources.htmlTree_tmpl.Replace("{KEYWORDS}", html);
}

public void process(ref Dictionary<string, string> _childs, ref string _html, string parent)
{
    var getChilds =
    from o in _childs
    where (o.Value == parent)
    select o.Key;

    foreach (var tmp in getChilds)
    {
        string child = tmp.ToString();

        if (_childs.ContainsValue(child))
        {
            _html += "<li id=\"" + child + "\">" + child + "<ul id=\"" + child + "\">";
            process(ref _childs, ref _html, child);
            _html += "</ul></li>";
        }
        else
        {
            _html += "<li id=\"" + child + "\">" + child + "</li>";
        }
    }

    return;
}

public class KeywordRows
{
    private string _keyword;
    private string _root_keyword;

    public KeywordRows(string keyword, string root_keyword)
    {
        _keyword = keyword;
        _root_keyword = root_keyword;
    }

    public string keyword
    {
        get
        {
            return _keyword;
        }
        set
        {
            _keyword = value;
        }
    }

    public string root_keyword
    {
        get
        {
            return _root_keyword;
        }
        set
        {
            _root_keyword = value;
        }
    }
}

}

我的问题是我有这个函数,我用它来将 2 列数据列表转换为嵌套的 html 树,问题是当该数据包含很多“行”时”,该函数需要很长时间才能完成,我没有遇到任何异常,但我让它以 100k 行数据作为输入运行大约 15 分钟,但它没有完成。

我整理了一个小型 Visual Studio 2010 项目来展示该问题,它模拟 X 大小的输入并执行该函数。

这是该项目: http://www.fileden.com/ files/2011/4/10/3112563//HTMLTreeTest.zip

我该怎么做才能更快地执行我的代码?

This is the code that is causing me "problems":

private string buildHTMLTree()
{
    Dictionary<string, string> parents = new Dictionary<string, string>();
    Dictionary<string, string> childs = new Dictionary<string, string>();
    ArrayList array = new ArrayList();
    array = simulateInput();

    string html = "";

    foreach (KeywordRows kwd in array)
    {
        if (kwd.root_keyword == kwd.keyword)
        {
            if (!parents.ContainsKey(kwd.keyword))
                parents.Add(kwd.keyword, kwd.root_keyword);
        }
        else
        {
            if (!childs.ContainsKey(kwd.keyword))
                childs.Add(kwd.keyword, kwd.root_keyword);
        }
    }

    html += "<ul id=\"parents\">";
    foreach (string parent in parents.Values)
    {
        html += "<li id=\"" + parent + "\">" + parent;

        if (childs.ContainsValue(parent))
        {
            html += "<ul id=\"parents\">";
            process(ref childs, ref html, parent);
            html += "</ul>";
        }

        html += "</li>";
    }
    html += "</ul>";

    return Properties.Resources.htmlTree_tmpl.Replace("{KEYWORDS}", html);
}

public void process(ref Dictionary<string, string> _childs, ref string _html, string parent)
{
    var getChilds =
    from o in _childs
    where (o.Value == parent)
    select o.Key;

    foreach (var tmp in getChilds)
    {
        string child = tmp.ToString();

        if (_childs.ContainsValue(child))
        {
            _html += "<li id=\"" + child + "\">" + child + "<ul id=\"" + child + "\">";
            process(ref _childs, ref _html, child);
            _html += "</ul></li>";
        }
        else
        {
            _html += "<li id=\"" + child + "\">" + child + "</li>";
        }
    }

    return;
}

public class KeywordRows
{
    private string _keyword;
    private string _root_keyword;

    public KeywordRows(string keyword, string root_keyword)
    {
        _keyword = keyword;
        _root_keyword = root_keyword;
    }

    public string keyword
    {
        get
        {
            return _keyword;
        }
        set
        {
            _keyword = value;
        }
    }

    public string root_keyword
    {
        get
        {
            return _root_keyword;
        }
        set
        {
            _root_keyword = value;
        }
    }
}

}

My problem is that I have this function I use to turn a 2 columns list of data to a nested html tree, the problem is that when this data contains a lot of "rows", the function takes forever to finish, I didn't got any exception but I let it ran with a 100k rows data as input for like 15 minutes and it didn't finished.

I've put together a small Visual Studio 2010 project to show the problem, it simulates an input of X size and executes the function.

Here's the project: http://www.fileden.com/files/2011/4/10/3112563//HTMLTreeTest.zip

What can I do to do my code (much) faster?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

起风了 2024-11-07 09:52:13

由于字符串连接,发布的代码可能会很慢。使用 StringBuilder 代替,或更专业的 HtmlTextWriter
这是使用 StringBuilder 的代码,它可以在更理智的时间内工作:
http://pastebin.com/0VrM6SLV

您也可以考虑直接写入您的 StreamWriter - 这可以避免一次性将整个字符串存储在内存中,这对于非常大的字符串来说是一个好主意。
该代码与使用 StringBuilder 非常相似。我们通过 strWri,并使用 StreamWriter.Write
http://pastebin.com/5afYdWHM
请注意,我必须拆分模板字符串(HTML 包装器)才能使其逻辑正常工作 - 如果我们不处理整个字符串,则无法使用 String.Replace

The posted code is likely to be slow due to string concatenation. Use a StringBuilder instead, or the more specialized HtmlTextWriter.
Here's your code with a StringBuilder, which works in saner time:
http://pastebin.com/0VrM6SLV

You may also consider writing directly to your StreamWriter - this avoids having the whole string in memory at once, which is a good idea for a very large string.
The code is very similar to using the StringBuilder. We pass strWri, and use StreamWriter.Write:
http://pastebin.com/5afYdWHM
Note that I had to split your template string (the HTML wrapper) to make it work logically - we can't use String.Replace if we aren't dealing with a whole string.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文