Scott
Scott

Reputation: 4210

Loop takes forever with large count

This loop takes forever to run as the amount of items in the loop approach anything close to and over 1,000, close to like 10 minutes. This needs to run fast for amounts all the way up to like 30-40 thousand.

'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 is a StringBuilder. The first line there

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

Runs in only a few seconds even with thousands of records. It's the actual loop that's taking a while.

How can this be optimized???

Upvotes: 0

Views: 730

Answers (6)

Mark Byers
Mark Byers

Reputation: 838826

I can't see how the code you have pointed out could be slow unless:

  • The strings you are dealing with are huggggge (e.g. if the resulting string is 1 gigabyte).
  • You have another process running on your machine consuming all your clock cycles.
  • You haven't got enough memory in your machine.

Try stepping through the code line by line and check that the strings contain the data that you expect, and check Task Manager to see how much memory your application is using and how much free memory you have.

Upvotes: 1

Reed Copsey
Reed Copsey

Reputation: 564691

Though, internally, the code is very similar, if you're using .NET 4, I'd consider replacing your method with a single call to String.Join:

Dim result as String = String.Join(Envionment.NewLine, lar.CreateLoanLines())

Upvotes: 1

btlog
btlog

Reputation: 4780

You could look at doing this another way.

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

Upvotes: 0

JSchlather
JSchlather

Reputation: 1603

My guess would be that every time you're using append it's creating a new string. You seem to know how much memory you'll need, if you allocate all of the memory first and then just copy it into memory it should run much faster. Although I may be confused as to how vb.net works.

Upvotes: 0

Peter Ruderman
Peter Ruderman

Reputation: 12485

Set the initial capacity of your StringBuilder to a large value. (Ideally, large enough to contain the entire final string.) Like so:

s = new StringBuilder(loans.Count * averageExpectedStringSize)

If you don't specify a capacity, the builder will likely end up doing a large amount of internal reallocations, and this will kill performance.

Upvotes: 2

Carl Manaster
Carl Manaster

Reputation: 40356

You could take the special case out of the loop, so you wouldn't need to be checking it inside the loop. I would expect this to have almost no impact on performance, however.

For i = 0 To last - 1
    s.AppendLine(loans(i))
Next
s.Append(loans(last))

Upvotes: 1

Related Questions