Forum Discussion

vex's avatar
vex
Contributor
13 years ago

Fast random string writes in TC

I wrote a program awhile back that randomly wrote data to a file that we used to perform file related stress/IO/etc.  This program is exceptionally fast, it can write a gig worth of data in just a few seconds.



I'm trying to write a similar routine in TC.  I understand that it will be considerably slower (unable to use pointers, etc), but I'm just trying to make it a feasible solution for most of our tests.  I assumed using the aqString/built in commands in TC would run faster.  The problem is that It's running exceptionally slow, much slower than I would have expected.  Again, I'm well aware this is going to be a lot slower than my other program, but I'd like it to at least be somewhat reasonable.



My goal is to be able to write a 1 meg file within 5 seconds using TC.



Here is the code I have so far (hardset values for testing):





  strDest = "c:\temp"

  intFiles = 1

  intSize = 1000

  strFile = "f"

  strExt = "doc"

 

  If intFiles = 0  Then intFiles = 100

  If intSize  = 0  Then intSize  = 1024

  If strFile  = "" Then strFile  = "f"

  If strExt   = "" Then strExt   = "doc"

 

  If strDest = "" Then

    Log.Warning "You must specify a destination!  No files have been written!"

    Exit Sub

  End If

 

  strDest = aqString.Trim(strDest, 3)

  If Right(strDest, 1) <> "\" Then strDest = strDest & "\"



  For t = 1 to intFiles

    f = strDest & strFile & t & "." & strExt

    Indicator.PushText "File: " & f & " , File: [" & t - 1 & " / " & intFiles & "]  (" & Int(((t-1)/intFiles) * 100) & " % complete)"

    fPos = 0



    If aqFile.Exists(f) Then

      aqFile.Delete(f)

    End If



    aqFile.Create(f)

    

    For v = 1 to intSize

      fData = ""

      For u = 1 to 1024

        fData = fData & Chr(32 + (rnd*223))

      Next

      Call aqFile.WriteToTextFile(f, fData, aqFile.ctANSI)

    Next              



  Next

  Indicator.PopText





Is there a faster way to manipulate strings in TC?  I'm pretty sure the slow down is occurring when I'm just appending a single character to an existing string.  However, the above method is a heck of a lot faster than the builtin methods.



I'd like to not have to use this external program and just incorporate everything into TC, which is why I'm seeing how feasible this is. If it isn't then I'll just shell out to the external program like we've been doing.
  • AlexeyK's avatar
    AlexeyK
    SmartBear Alumni (Retired)

    Hi Vince,


    The string concatenation operation is typically quite slow. You are right that in TestComplete, it will work slower as compared to your application.

    However, in your case, I'd suggest that you change the approach of writing data to the file you create.

    Look at your code, you are using the aqFile.WriteToTextFile method:




    ...

        For v = 1 to intSize

          fData = ""

          For u = 1 to 1024

            fData = fData & Chr(32 + (rnd*223))

          Next

          Call aqFile.WriteToTextFile(f, fData, aqFile.ctANSI)

        Next             

    ...


    To write data to a file, this method opens the file for writing, writes data to the file and then closes the file. These operations are time-consuming. Also, your test performs it in each step of the loop. I'd suggest changing the way you work with the file: open a file once, write data to it, close the file:




    ..

        aqFile.Create(f)

       

        ' Open the file

        Set textFile = aqFile.OpenTextFile(f, aqFile.faWrite, aqFile.ctANSI)

       

        For v = 1 to intSize

          ' Generate string here

          ' fData = ...

          Call textFile.Write(fData)  ' Write data to the file

        Next             


        textFile.Close  ' Close the file

    ...


    As far as I can see, this code dramatically reduces the test execution time on my computer. Generating a 1Mb-file now takes about 2 seconds.


    Another area you can improve is generation of a string that contains 1024 characters. As far as I can see, you are interested in the string contents, so you can use VBScript's String function, for example:


      fData = String(1024, "A")


    Replacing a loop with this code reduces the file generation time to 0.3-0.4 seconds on my computer.

  • vex's avatar
    vex
    Contributor
    Alex,



    Thanks for heads up!  I didn't know that it would open/write/close with the one function.  That sped things up considerably.  It's now at least usable for me :)



    I do know about the String command, but I have to generate random data for the purpose of the test.  I can't do it in 1k blocks.