代码之家  ›  专栏  ›  技术社区  ›  Scott

循环需要大量的时间

  •  0
  • Scott  · 技术社区  · 14 年前

    这个循环需要永远运行,因为循环中的项目数量接近或超过1000个,接近10分钟。这需要快速运行的金额,一路高达3-4万。

    'Add all Loan Record Lines
    Dim loans As List(Of String) = lar.CreateLoanLines()
    Dim last As Integer = loans.Count - 1
    For i = 0 To last
        If i = last Then
            s.Append(loans(i))
        Else
            s.AppendLine(loans(i))
        End If
    Next
    

    S是一个字符串生成器。那里的第一行

    Dim loans As List(Of String) = lar.CreateLoanLines()
    

    即使有数千条记录,也只需几秒钟即可运行。这是需要一段时间的实际循环。

    如何优化????

    6 回复  |  直到 14 年前
        1
  •  2
  •   Peter Ruderman    14 年前

    将StringBuilder的初始容量设置为大值。(理想情况下,足够大以包含整个最终字符串。)如:

    s = new StringBuilder(loans.Count * averageExpectedStringSize)
    

    如果不指定容量,构建器可能会进行大量的内部重新分配,这将扼杀性能。

        2
  •  1
  •   Carl Manaster    14 年前

    你可以把特殊情况从循环中去掉,这样你就不需要在循环中检查它了。不过,我希望这对性能几乎没有影响。

    For i = 0 To last - 1
        s.AppendLine(loans(i))
    Next
    s.Append(loans(last))
    
        3
  •  1
  •   Reed Copsey    14 年前

    但是,在内部,代码非常相似,如果您使用.NET 4,我会考虑用对 String.Join :

    Dim result as String = String.Join(Envionment.NewLine, lar.CreateLoanLines())
    
        4
  •  1
  •   Mark Byers    14 年前

    我看不出你指出的代码有多慢,除非:

    • 您要处理的字符串是huggggge(例如,如果得到的字符串是1 GB)。
    • 您的机器上运行的另一个进程占用了您的所有时钟周期。
    • 你的机器内存不足。

    尝试一行一行地遍历代码,检查字符串是否包含您期望的数据,并检查任务管理器,以查看应用程序使用的内存量和可用内存量。

        5
  •  0
  •   JSchlather    14 年前

    我猜每次使用append都会创建一个新字符串。你似乎知道你需要多少内存,如果你先分配所有的内存,然后把它复制到内存中,它应该运行得更快。尽管我可能对vb.net的工作方式感到困惑。

        6
  •  0
  •   btlog Stefan Wick MSFT    14 年前

    你可以从另一个角度来看。

    Dim str As String = String.Join(Environment.NewLine, loans.ToArray)