【问题标题】:why for loop is taking too much time in given java code为什么for循环在给定的Java代码中花费了太多时间
【发布时间】:2017-02-14 09:33:15
【问题描述】:

如何减少 for 循环所花费的时间,如果可能的话,使用 replaceAll(,) 方法删除 for 循环:

String extractText(String s) throws IOException
{
    String html = fj.toHtmlString(s); //extracted html source code from wikipedia
    String filtered_text="";
    System.out.println("extracted \n\n");
    String []html_text = html.split("\n");
    long start = System.currentTimeMillis();

    for(String h:html_text)
    {   //System.out.println("ky4"+h);
        if(Pattern.compile("</strong>", Pattern.CASE_INSENSITIVE + Pattern.LITERAL).matcher(h).find())
        {

        }
        else if(Pattern.compile("<strong", Pattern.CASE_INSENSITIVE + Pattern.LITERAL).matcher(h).find())
        {

        }
        else
        {
            filtered_text += h;
            filtered_text += "\n";
        }
    }
    long end = System.currentTimeMillis();
    System.out.println("loop end in "+(end-start)/1000+" seconds"+" or "+(end-start)+" miliseconds");//System.out.println(++i2+" th loop end in "+(end-start)/1000+" seconds");
    return filtered_text;
}

【问题讨论】:

  • 是代码审查反馈吗?
  • 您在 for 循环中创建了不必要的对象。
  • 所以我要求尽可能使用 replaceAll() 方法替换整个 for 循环代码,我该怎么办?
  • 如果我从这个“en.wikipedia.org/wiki/Varanasi”URL 中提取 html 源代码,for 循环需要大约 6 秒来计算逻辑

标签: java regex for-loop


【解决方案1】:

让我们看一下循环:

for(String h:html_text)
{   //System.out.println("ky4"+h);
    if(Pattern.compile("</strong>", Pattern.CASE_INSENSITIVE + Pattern.LITERAL).matcher(h).find())
    {

    }
    else if(Pattern.compile("<strong", Pattern.CASE_INSENSITIVE + Pattern.LITERAL).matcher(h).find())
    {

    }
    else
    {
        filtered_text += h;
        filtered_text += "\n";
    }
}

每次循环时至少要编译一个正则表达式,这非常耗时。改用变量:

Pattern endingTag = Pattern.compile("</strong>", Pattern.CASE_INSENSITIVE + Pattern.LITERAL);
Pattern startTag = Pattern.compile("<strong", Pattern.CASE_INSENSITIVE + Pattern.LITERAL)
for(String h:html_text)
{   //System.out.println("ky4"+h);
    if(endingTag.matcher(h).find())
    {}
    else if(startTag.matcher(h).find())
    {}
    else
    {
        filtered_text += h;
        filtered_text += "\n";
    }
}

这将为您节省大量时间。另外,请注意,当您衡量性能时,请始终在发布模式下运行。

【讨论】:

    【解决方案2】:

    您可以尝试在循环之前编译您的模式,而不是在其中:

    String extractText(String s) throws IOException
    {
        String html = fj.toHtmlString(s); //extracted html source code from wikipedia
        String filtered_text="";
        System.out.println("extracted \n\n");
        String []html_text = html.split("\n");
        long start = System.currentTimeMillis();
        Pattern end = Pattern.compile("</strong>", Pattern.CASE_INSENSITIVE + Pattern.LITERAL)
        Pattern start = Pattern.compile("<strong", Pattern.CASE_INSENSITIVE + Pattern.LITERAL)
        for(String h:html_text)
    

    【讨论】:

    • 好的,以上这些解决方案可以减少对象创建的时间,但我的问题没有解决,我意识到当从维基百科批量提取文本时,循环需要很长时间来逐行计算文本,所以我想从代码中删除循环
    • 请建议我在不存在循环的情况下完成相同工作的任何其他逻辑,如果可能的话,您可以使用 replaceAll() 方法
    • 你想达到什么目的?
    【解决方案3】:

    以下代码解决了我的问题:

    String extractText(String s) throws IOException
    {
        String html = fj.toHtmlString(s); 
        String filtered_text="";
        System.out.println("extracted \n\n");
        html=html.replaceAll("(?i)</strong>", "");
        html=html.replaceAll("(?i)<strong[^>]*>", "");
        filtered_text = html;        
        long end = System.currentTimeMillis();
        System.out.println("loop end in "+(end-start)/1000+" seconds"+" or "+(end-start)+" miliseconds");//System.out.println(++i2+" th loop end in "+(end-start)/1000+" seconds");
        return filtered_text;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-13
      • 2016-12-08
      • 2018-09-20
      • 2020-07-17
      • 1970-01-01
      • 2019-07-06
      • 2017-03-20
      相关资源
      最近更新 更多