Question

Faster Way to Get String

Asked by: TheAnswerMan

I know that String concatenation is slow.
What is the faster way to build a string?
the following is a comma delimited list of numbers from 1 to 10000
Dim x as long
dim ls_String as string

for x = 1 to 10000
    ls_String = ls_String & Cstr(x) & ","
next x
ls_string = left$(ls_string,len(ls_String)-1)


What is a faster way?
Bonus points for butt fast code.

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
1999-08-09 at 11:38:59ID10192415
Topic

Visual Basic Programming

Participating Experts
6
Points
50
Comments
9

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. CStr(Object) vs Object.ToString
    I use Option Strict On which often forces me to convert objects into strings. I have two options to do so: Using CStr as in CStr(myVariable) or using .ToString as in myVariable.ToString The second seems to be logically the one to use, but very often .ToString does not appe...

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: EDDYKTPosted on 1999-08-09 at 11:48:33ID: 1530622

Paste the following to class module

------
Option Explicit
'Faster concatenation of strings in VB.
'-Dave Hng, 12 February 1999, based on Q170964 in the VB KB
'I just prefer to use Nulls instead of spaces
Private sBuffer As String
Private Const ciIncriment As Integer = 15000
Private lOffset As Long
'This function returns the concating buffer.


Public Function GetString() As String

    GetString = Left$(sBuffer, lOffset)
End Function

'This function lets you assign a string to the concating buffer.


Public Sub SetString(ByRef Source As String)

    sBuffer = Source & String$(ciIncriment, 0)
End Sub

'This is what does the work.


Public Sub Concat(ByRef Source As String)

    Dim lBufferLen As Long
    lBufferLen = Len(Source)
    'If you need more space in the buffer then allocate some.


    If (lOffset + lBufferLen) >= Len(sBuffer) Then


        If lBufferLen > lOffset Then
            sBuffer = sBuffer & String$(lBufferLen, 0)
        Else
            sBuffer = sBuffer & String$(ciIncriment, 0)
        End If

    End If

    Mid$(sBuffer, lOffset + 1, lBufferLen) = Source
    lOffset = lOffset + lBufferLen
End Sub


-----


On your form


Private Sub Command2_Click()

   
    Dim clsConcat As New clsStringConcat
    Dim x As Long
   
    For x = 1 To 10000
        clsConcat.Concat CStr(x) & ","
    Next x
   Debug.Print clsConcat.GetString
End Sub

 

by: TheAnswerManPosted on 1999-08-09 at 12:26:32ID: 1530623

I guess it does it OK I'll add more data to my example of what I have.  The class module appears to do about the same thing.
I ran  the class example and it started out ok then got slower and slower, then it ran out of memory on my 128 MB Machine. then the Program took a massive dump and disappeared.  WinNT


Here is a more detailed Example

dim ls_Row as string            ' Will contain all the Data for a Row in a resultset
dim li_LenSoFar as long        ' Will contain the length of the String's useful characters
dim lr_Res as rdoResultset      '= a resultset <or recordset doesnt matter>

'INIT ----------
ls_Row = String$(65000, vbKeySpace) 'Gimmie some space for string.
                              'Assume max 255 columns * Max 255 max length per column

'MAIN ----------
if not lr_Res.EOF then
    For x = 0 To lr_Res.rdoColumns.Count - 1    ' go through each column in the resultset
        If IsNull(lr_Res(x)) Then
           Mid$(ls_Row, li_LenSoFar + 1, 7) = "<NULL>,"   ' if null then give me this instead
           li_LenSoFar = li_LenSoFar + 7               ' add to the count of the length
        Else
           ls_Col = CStr(lr_Res(x)) & ","
           Mid$(ls_Row, li_LenSoFar + 1, Len(ls_Col)) = ls_Col      'go to the first Available space and add the text
           li_LenSoFar = li_LenSoFar + Len(ls_Col) + 1            ' add to the count of the length
        End If
    Next x 'Next column
end if

'RESULTS -------
ls_Row = left$(ls_Row,li_Lensofar - 1) ' trim the last comma
msgbox ls_Row                      ' msgbox of a comma delimited row


'End Example

I had read that Byte Arrays would be faster.

 

by: TheAnswerManPosted on 1999-08-09 at 12:58:24ID: 1530624

the above example might return something like
"0001,Test-Dept,Bill Smith,555-1212"

 

by: AnswerTheManPosted on 1999-08-09 at 14:40:29ID: 1530625

before i read your enlarge example - i'm reffering to
your short original question.
FIRST - you can ommit the Cstr fonction from the loop.
10000 times calling that F is time, and you don't need that
in VB.
SECOND - CPU and memory works harder and harder to retrive
the string again and again, and its getting longer makes things harder.
if you run into such prob - you've better write every 500-1000 bytes or so into an array of strings.
you can prepare that array from advance, or you can RedimPreserve it as the proccess needs. every 500 or so - add a new string to the array.
THIRD - if it's really really really BIG - consider writing
all every 500 0r 1000 to FILE. Don't shout NO !!! FILE is slow allright, but as you write the 1000 to the file - you free MEMORY as CPU, and you go on fresh new.


 

by: zeuskrellPosted on 1999-08-09 at 15:57:46ID: 1530626

This may not be what you are looking for because it still does use the ampersand bu it runs about 20 times faster using simply better techniques than your method here it is:

Private Sub Command1_Click()
Dim x As Long
Dim ls_String As String
Dim ls_tmp As String
Text1 = Time
Text1.Refresh

For x = 0 To 99
    ls_tmp = ""
    For y = 1 To 100 Step 10
        ls_tmp = ls_tmp & CStr(x * 100 + y) & "," & CStr(x * 100 + y + 1) & "," & CStr(x * 100 + y + 2) & "," & CStr(x * 100 + y + 3) & "," & CStr(x * 100 + y + 4) & "," & CStr(x * 100 + y + 5) & "," & CStr(x * 100 + y + 6) & "," & CStr(x * 100 + y + 7) & "," & CStr(x * 100 + y + 8) & "," & CStr(x * 100 + y + 9) & ","
        Text2 = Str(x)
        Text2.Refresh
    Next y
    ls_String = ls_String & ls_tmp
Next x
ls_String = Left$(ls_String, Len(ls_String) - 1)

Text2 = Time
Text2.Refresh
Stop
End Sub

I put a STOP so you could see the string is the same as your original coded string.  The two techniques is to append to shorter strings then every so often append the short string to the large one.  This prevents the sluggishness of moving the big string thousands of times into itself as it reaches the full size later on.  Also notice that if you know what is going to be appended as we do that it is quicker using math to append ten at a time instead of one by one.  More code but huge speed increases doing the same thing you did very slowly with a single loop.

Most likely the only other answer will be to use something other than VB to accomplish this such as a DLL as with the Crescent QuickPak includes a DLL with many high speed functions you can call with functions similar to an API call.  

One last idea would be to use a control such as a richtext box or other box which can hold a huge amount of text and may provide for a pointer as to tell it where to insert your appended text.  This may use faster machine code or 'C' code to do the append insert where you can then grab the entire contents and assign to a string when done.  If its a visible textbox you may need to make it invisible to speed it up so it doesnt try to display each append.

 

by: amebaPosted on 1999-08-09 at 20:30:41ID: 1530627

1. It is very slow to loop through recordset. You should use GetRows method of your recordset - array looping is much faster.
2. Calculate the total size of your string - don't do this in chunks, appending 15K many times IS concatenation. You'll probably need two passes - first for getting total length, second for a real job.
3. Allocate space by using:
    bigstring = Space(totallength)    ' String(totallength, 32) is not good for big (many MBs) strings
bigstring or big array must be declared at module level to avoid stack error.
4. If you ommit the Cstr fonction, VB will still have to convert number to string. There is no speed difference.

See also my 'fast replace' code (10 pts):
http://www.experts-exchange.com/Q.10189972

' 1-10000 code
Option Explicit
DefLng I-Z
Private Declare Function GetTickCount Lib "kernel32" () As Long

Private Sub Form_Click()
    Const delim As String = ";"
    Dim x, tim0, maxlen, pos, i, lb, ub
    Dim ls_String As String
    ' start timer
    tim0 = GetTickCount
    ' calculate length of our string
    maxlen = 9 * 2                 ' 1...9
    maxlen = maxlen + 90 * 3       ' 10...99
    maxlen = maxlen + 900 * 4      ' 100...999
    maxlen = maxlen + 9001& * 5    ' 1000...10000
    ' create new string
    ls_String = String(maxlen, ";")

    pos = 1
    For i = 1 To 4
        lb = Choose(i, 1, 10, 100, 1000)
        ub = Choose(i, 9, 99, 999, 9999)
        For x = lb To ub
            Mid(ls_String, pos, i) = CStr(x)
            'Mid(ls_String, pos + i, 1) = delim
            pos = pos + i + 1
        Next
    Next
    Mid(ls_String, pos, i) = CStr(x)
    ' report time
    Print (GetTickCount - tim0) / 1000 & " seconds"
End Sub

 

by: Jeremy_DPosted on 1999-08-10 at 01:00:41ID: 1530628

Try the following (or something like it, using the GetString method), it should be the fastest way of getting a recordset in a string by far:

ls_Row = ls_Res.GetString(adClipString, , ",", ",", "<NULL>")

This also gives you the same result with only one line of code.

Good luck,
Jeremy


 

by: LewyPosted on 1999-08-17 at 14:39:07ID: 1530629

Dim x as integer, L as integer, P as integer
dim ls_String as string, T$, Comma$
P = 1
Comma$ = ","
ls_String = String(32767,0)
for x = 1 to 10000
    T$ = Cstr(x)
    L = len(T$)
    mid$(ls_String,P,L) = T$
    mid$(ls_String,P + L + 1 ,1) = Comma$
    P = P+L+1
next x
ls_string = left$(ls_string,P-1)



 

by: amebaPosted on 1999-08-28 at 17:18:25ID: 1530630

>Bonus points for butt fast code.
Please check solutions and award points!
Thanks

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...