Coding C in Basic
Bruce: What do you mean?
Joe: Look what you’re doing every time you call StrSpan or StrBreak. You’re cutting off the remaining part of the string and passing it as an argument. That would work fine in C because C just passes pointers to strings. The whole string stays put in memory, but you’re pointing only to the tail end of it. But in Basic, when you pass the result of Mid$ to a function, you create a new temporary string. It’s a separate string that has to be created for the function it’s passed to and then destroyed when the function leaves. You don’t want to create any more new strings than you need.
Bruce: Well, OK, but how do I keep from creating new strings?
Joe: You just pass one string—sSave—but you also pass the current position.
Jane: But that means changing the design of StrSpan and StrBreak.
Joe: Yeah. So the call changes from
iNew = StrSpan1(Mid$(sSave, iStart), sSeps)
to
iNew = StrSpan2(sSave, iStart, sSeps)
Then your StrSpan implementation changes to this:
Function StrSpan2(sTarget As String, ByVal iStart As Integer, _
sSeps As String) As Integer
Dim cTarget As Integer
cTarget = Len(sTarget)
‘ Look for start of token (character that isn’t a separator)
Do While InStr(sSeps, Mid$(sTarget, iStart, 1))
If iStart > cTarget Then
StrSpan2 = 0
Exit Function
Else
iStart = iStart + 1
End If
Loop
StrSpan2 = iStart
End Function
Jane: But you’re making StrSpan and StrBreak harder to use. They get a confusing extra argument. I mean, who’d guess how to use these things from the arguments?
Joe: That’s just how Basic works. Nothing but GetToken will call them anyway. If anybody else did use them, they’d have to deal with the same efficiency problem. If you don’t like Basic, use C.
Mary: Joe, sometimes I wonder why a guy who hates Basic so much chooses to work on it. You just like to criticize, and Basic is an easy target.
Jane: He’s not as tough as he acts. Actually, he has a soft spot for Basic.
Bruce: Instead of criticizing the language, you ought to fix it. Look how I have to use this stupid Mid$ function just to get a character out of a string:
Do While InStr(sSeps, Mid$(sTarget, iStart, 1))
In most languages, you access a character in a string the same way you access an element in an array of bytes—maybe something like this:
Do While InStr(sSeps, sTarget(iStart))
I hope that, internally, you’re at least optimizing the special case of extracting a single character.
Joe: Well, I’m not sure….There might not be anything we could do. A one-character string is no different from any other string in Basic.
Mary: Maybe you should make sure. Check the code.
Archaeologist’s Note: We have no record of whether the changes Joe suggested resulted in any performance benefit in the ancient Basic language of the day, but the same changes in modern Visual Basic provide a 19 percent performance improvement even after improving the error checking. However, you still have to use Mid$ to extract a single character.