?
Solved

Reading characters in a string.

Posted on 2001-07-10
18
Medium Priority
?
256 Views
Last Modified: 2007-12-19
I have a function that takes a compressed string, uncompresses it, and returns the uncompressed string.  The compression is very simple.  When 3 or more consecutive spaces or zeroes are encountered, they are removed and replaced with a flag (ASCII 126 for zeroes and ASCII 127 for spaces) and the binary number of spaces or zeroes.  All of this works properly.

My problem is that when I create an EXE, the program takes 2 to 3 times longer to uncompress the string than just running the program through the VB IDE.  Both are running the exact same code.

Any ideas on what the problem could be?  I can post the code if it will help.

0
Comment
Question by:brandonb
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 5
  • 4
  • +2
18 Comments
 
LVL 3

Expert Comment

by:jrspano
ID: 6270593
post the code.
0
 
LVL 2

Expert Comment

by:exelrud
ID: 6270620
Is this a function or do you create another process to handle the uncompression or do it on the idle time ?
0
 
LVL 1

Author Comment

by:brandonb
ID: 6270646
Here is the code.  One other thing to mention about the compression is that if there are ASCII characters > 123, the compression routine doubles them as a way to let the uncompression routine know that they are truly characters not flags.

This is a function that is called from a .BAS module.

Function Uncompress_String(TalkInputString As String)

    Dim Char As String
    Dim NextChar As String
    Dim Cntr As Integer

    Uncompress_String = ""
   
    For X = 1 To Len(TalkInputString)
        Char = Mid$(TalkInputString, X, 1)
        If Char > Chr$(123) Then
            NextChar = Mid$(TalkInputString, X + 1, 1)
        End If
       
        If Char > Chr$(123) And Char = NextChar Then
            Uncompress_String = Uncompress_String + Char
        Else
            If Char = Chr$(126) Or Char = Chr$(127) Then
                Cntr = Asc(NextChar)
                    If Char = Chr$(127) Then
                        Uncompress_String = Uncompress_String + String(Cntr, " ")
                    Else
                        Uncompress_String = Uncompress_String + String(Cntr, "0")
                    End If
                X = X + 1
            Else
                Uncompress_String = Uncompress_String + Char
            End If
        End If
       
    Next X
   
End Function
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 2

Expert Comment

by:exelrud
ID: 6270683
I do not like using X = X + 1 inside a for X
change the for X for a while just to be sure.
The compiler otimizations may conflict with what you're trying to do (skip a char)
0
 
LVL 2

Expert Comment

by:exelrud
ID: 6270685
Ooops.
Change the for into a While.
0
 
LVL 38

Expert Comment

by:PaulHews
ID: 6270835
This kind of manipulation would be a lot faster in a byte array.
0
 
LVL 1

Author Comment

by:brandonb
ID: 6270946
PaulHews,
I haven't ever used a byte array.  Could you give me an example?  Speed is of the utmost importance.  This is a piece of a communications package between a UNIX C program and a VB program.  Some of our sites use a 56K lease line.  We have experimented with gzip compression, but found this simple compression gives us the best combination of compression and processing time.  Anything that would speed up the compression/uncompression would be greatly appreciated.

exelrud,
I understand the concern with adding 1 to X, but would I not have the same problem running the program through the IDE?
0
 
LVL 2

Accepted Solution

by:
exelrud earned 400 total points
ID: 6270974
Maybe so, maybe not.
The debug environment may act in a different way then the compiled code.
It should behave the same but "should" and "does" and 2 different words...
0
 
LVL 38

Expert Comment

by:PaulHews
ID: 6271022
This is what I mean...  I can't really test this, so there may be bugs, but it is the broad idea of what I mean:

Function Uncompress_String(TalkInputString As String) As String

   Dim Char As Byte
   Dim NextChar As Byte
   Dim Cntr As Integer
   Dim bytInputString() As Byte
   Dim bytUncompressedString() As Byte  'Output string
   Dim intChunkSize As Integer  'used to allocate memory in 1K blocks (faster)
   Dim intCount As Integer  'incremented for each addition to output
   'AscII constants
   Const chSpace As Byte = 32
   Const chZero As Byte = 48
   
   intChunkSize = 1024
    bytInputString = StrConv(TalkInputString, vbFromUnicode)  'Convert string to bytes
   
'   Uncompress_String = ""
   intCount = 0
   
   For X = 1 To Len(TalkInputString)
       Char = bytInputString(i - 1) 'Mid$(TalkInputString, X, 1)
       If Char > 123 Then
           NextChar = bytInputString(i - 1) 'Mid$(TalkInputString, X + 1, 1)
       End If
       
       If Char > 123 And Char = NextChar Then
            'This code could go in a sub for readability, but a little faster inline.  :)
            intCount = intCount + 1
            If intCount > intChunkSize Then
                intChunkSize = intChunkSize + 1024
                ReDim Preserve bytUncompressedString(1 To intChunkSize)
            End If
            bytUncompressedString(intCount) = Char
           
           'Uncompress_String = Uncompress_String + Char
       Else
           If Char = 126 Or Char = 127 Then
               Cntr = NextChar
                    intCount = intCount + 1
                    If intCount > intChunkSize Then
                        intChunkSize = intChunkSize + 1024
                        ReDim Preserve bytUncompressedString(1 To intChunkSize)
                    End If
                   
                   If Char = 127 Then
                        bytUncompressedString(intCount) = chSpace
'                       Uncompress_String = Uncompress_String + String(Cntr, " ")
                   Else
                        bytUncompressedString(intCount) = chZero
'                       Uncompress_String = Uncompress_String + String(Cntr, "0")
                   End If
               X = X + 1
           Else
                intCount = intCount + 1
                If intCount > intChunkSize Then
                    intChunkSize = intChunkSize + 1024
                    ReDim Preserve bytUncompressedString(1 To intChunkSize)
                End If
                bytUncompressedString(intCount) = Char
'               Uncompress_String = Uncompress_String + Char
           End If
       End If
       
   Next X
   Uncompress_String = StrConv(bytUncompressedString, vbUnicode)   'Convert bytes back to string
   
End Function
0
 
LVL 38

Expert Comment

by:PaulHews
ID: 6271024
Commented out your code where mine was different...

This should perform significantly faster, especially if the strings are long.
0
 
LVL 38

Expert Comment

by:PaulHews
ID: 6271029
Found one bug already:

If Char > 123 Then
          NextChar = bytInputString(i) 'Mid$(TalkInputString, X + 1, 1)
      End If
0
 
LVL 1

Author Comment

by:brandonb
ID: 6271088
I'm going to give both of you points for your help.  exelrud seems to have solved my problem and I'm just beginning to test PaulHews code.
0
 
LVL 14

Expert Comment

by:wsh2
ID: 6271308
Built for speed.. <smile>

=====================================================
1. Start a New Standard.Exe Project.
2. Copy/Paste the following into the Form1 code window.
3. Press F8 to Run. The contents of strWork will appear in a MsgBox.

<----- Code Begin ----->
Option Explicit

Private Sub Form_Load()
   
   Dim strWork As String
   strWork = "a" & Chr(127) & Chr(12) & "b"
   MsgBox Uncompress_String(strWork)

End Sub

Function Uncompress_String(TalkInputString As String)

   Dim bytGet() As Byte: ReDim bytGet(Len(TalkInputString) * 1)
   Dim lngGet As Long: lngGet = 0
   Dim bytPut() As Byte: ReDim bytPut(Len(TalkInputString) * 2) ' Estimate
   Dim lngPut As Long: lngPut = 0
   Dim lngX As Long
   
   bytGet() = StrConv(TalkInputString & ":", vbFromUnicode)

   For lngGet = LBound(bytGet) To UBound(bytGet) - 1
      If (bytGet(lngGet) = 126 And bytGet(lngGet + 1) <> 126) _
      Or (bytGet(lngGet) = 127 And bytGet(lngGet + 1) <> 127) _
      Then
         For lngX = 1 To bytGet(lngGet + 1)
            Select Case bytGet(lngGet)
               Case 126
                  bytPut(lngPut) = Asc(" ")
               Case 127
                  bytPut(lngPut) = Asc("0")
            End Select
            lngPut = lngPut + 1
            If lngPut >= UBound(bytPut) Then
               ReDim Preserve bytPut(lngPut)
            End If
         Next lngX
         lngGet = lngGet + 1
      Else
         If bytGet(lngGet) > 123 And bytGet(lngGet) = bytGet(lngGet + 1) Then
            lngGet = lngGet + 1
         End If
         bytPut(lngPut) = bytGet(lngGet)
         lngPut = lngPut + 1
         If lngPut >= UBound(bytPut) Then
            ReDim Preserve bytPut(lngPut)
         End If
      End If
   Next lngGet
   
   ReDim Preserve bytPut(lngPut - 1)
   Uncompress_String = StrConv(bytPut(), vbUnicode)
   
End Function

<----- Code End ----->
0
 
LVL 1

Author Comment

by:brandonb
ID: 6274415
wsh2,
Your code works great except if I change anything after pasting the code in my program.  If I add some blank lines or realign the beginning of each line with the program, I receive the following error when I try to run the program.  Sometimes, when VB restarts, the error doesn't occur again, but other times it still does.  Any ideas?

The instruction at "0x0facb9ac" referenced memory at "0x00000000". The memory could not be "read".

Click on OK to terminate the program
Click on CANCEL to debug the program
0
 
LVL 14

Expert Comment

by:wsh2
ID: 6276449
brandonb..

It sounds like your copy of Visual Basic is corrupt.. <sigh>. You may want to consider reinstalling it and applying VB6 SP5 which you can get at this URL address:

http://msdn.microsoft.com/vstudio/sp/vs6sp5
0
 
LVL 1

Author Comment

by:brandonb
ID: 6294921
Thanks for help everyone.
0
 
LVL 38

Expert Comment

by:PaulHews
ID: 6294933
Ah.  Did you intentionally choose that answer, or was it a mistake.
0
 
LVL 1

Author Comment

by:brandonb
ID: 6294987
Intentionally.  exelrud's suggestion solved my original problem.

Check the question list.  There should be a "question" just for you for your help with the byte array.

BTW, the error I was receiving has something to do with the code not VB being corrupt.  I haven't had the time to narrow it down, but I modified PaulHews code and it works wonderfully.
0

Featured Post

New benefit for Premium Members - Upgrade now!

Ready to get started with anonymous questions today? It's easy! Learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
Suggested Courses
Course of the Month7 days, 23 hours left to enroll

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question