|
楼主 |
发表于 2016-6-29 01:42
|
显示全部楼层
Mid$高速生成长字符串
大家都知道, &操作符的执行速度是相当慢的,特别是处理长字符串时.当必须重复地在同一变量上附加字符时,有一个基于Mid$命令的技巧可以使用.基本思路就是:预留一个足够长的空间存放操作的结果.下面是应用这个技术的一个例子.
假设要建立一个字符串,它要附加从1开始的10000个整数:"1 2 3 4 5 6 7 ... 9999 10000".下面是最简单的实现代码:res = ""
For i = 1 to 10000
res = res & Str(i)
Next
复制代码 代码虽然简单,但问题也很明显:Res变量将被重分配10000次.下面的代码实现同样的目的,但效果明显好转:Dim res As String
Dim i As Long
Dim index As Long
‘预留足够长的缓冲空间
res = Space(90000)
‘指针变量,指出在哪里插入字符串
index = 1
‘循环开始
For i = 1 to 10000
substr = Str(i)
length = Len(substr)
‘填充字符串的相应区间段数值
Mid$(res, index, length) = substr
‘调整指针变量
index = index + length
Next
‘删除多余字符
res = Left$(res, index - 1)
复制代码 测试表明:在一个333MHz的计算机上,前段代码执行时间为2.2秒,后者仅仅为0.08秒!代码虽然长了些,可是速度却提高了25倍之多.呵呵,由此看来:代码也不可貌相啊(看样子,代码并不一定短才好)
=================我是分割线===============
用InStr函数实现代码减肥
可以采用”旁门左道”的方式使用Instr函数实现代码的简练.下面是一个典型的例子,检测字符是否是一个元音字母:
1、普通的方法:If UCase$(char) = "A" Or UCase$(char) = "E" Or UCase$(char) = "I" Or UCase$(char) = "O" Or UCase$(char) = "U" Then
' it is a vowel
End If
'VBA中例子函数
Function 是否元音字母1(char As String) As Boolean
是否元音字母 = False
If UCase$(char) = "A" Or UCase$(char) = "E" Or UCase$(char) = "I" Or UCase$(char) = "O" Or UCase$(char) = "U" Then
是否元音字母 = True
End If
End Function
复制代码 2、更加简练的方法:If InStr("AaEeIiOoUu", char) Then
' it is a vowel
End If
'VBA中例子函数
Function 是否元音字母2(char As String) As Boolean
是否元音字母 = False
If InStr("AaEeIiOoUu", char) Then
是否元音字母 = True
End If
End Function
复制代码同样,通过单词中没有的字符作为分界符,使用InStr来检查变量的内容.下面的例子检查Word中是否包含一个季节的名字:
1、普通的方法:If LCase$(word) = "winter" Or LCase$(word) = "spring" Or LCase$(word) = "summer" Or LCase$(word) = "fall" Then
'it is a season's name这是一个季节名称??
End If
复制代码 2、更加简练的方法:If Instr(";winter;spring;summer;fall;", ";" & word & ";") Then
' it is a season's name
End If
复制代码有时候,甚至可以使用InStr来替代Select Case代码段,但一定要注意参数中的字符数目.下面的例子中,转换数字0到9的相应英文名称为阿拉伯数字: (下面这个太高档了,很难想到)
1、普通的方法:Select Case LCase$(word)
Case "zero"
result = 0
Case "one"
result = 1
Case "two"
result = 2
Case "three"
result = 3
Case "four"
result = 4
Case "five"
result = 5
Case "six"
result = 6
Case "seven"
result = 7
Case "eight"
result = 8
Case "nine"
result = 9
End Select
复制代码 2、更加简练的方法:result =InStr(";zero;;one;;;two;;;three;four;;five;;six;;;seven;eight;nine;", ";" & LCase$(word) & ";") \ 6
复制代码——怎么样?这个是比较变态吧,很难想到,不过确实很巧妙。很难想象吧,上面那么长一段代码这里就这一句就搞定了
======================我也是分割线======================
使用"$-类型"字符串函数会更快
——在这里确实很少见到大家用含$的函数,本人也是偶尔用用,我原来的那本VB6教材中还是有介绍的
VB官方文档似乎很鼓励使用"无$"类字符串函数,比如:Left、LTrim或者UCase,而不是实现同样功能的Left$、LTrim$和UCase$函数.但是我们必须认识到:前者返回variant类型的数值,当用于字符串表达式中时,最终必须要转换为字符串(string)类型. 因此,在严格要求时间的代码段中,我们应该使用后者,它们将快5-10%.
=======================又见分割线=======================
妙用Replace函数替代字符串连接操作符&
你大概不知道Replace函数还能这么用吧?比如下面的语句:MsgBox "Disk not ready." & vbCr & vbCr & _
"Please check that the diskette is in the drive" & vbCr & _
"and that the drive's door is closed."
复制代码可以看出,为了显示完整的字符串含义,要将可打印字符与非打印字符(比如:回车符vbCr)用&符号连接在一起.结果是:长长的字符连接串变得难于阅读.但是,使用Replace函数,可以巧妙地解决这个问题.方法就是:将非打印字符以字符串中不出现的一个可打印字符表示,这样完整地写出整个字符串,然后使用Replace函数替换那个特别的打印字符为非打印字符(比如:回车符vbCr).代码如下:MsgBox Replace("Disk not ready.§§Please check that the diskette is in the " _
& "drive§and that the drive's door is closed.", "§", vbCr)
复制代码注:这个可真的没有想到过,汗一个::L
=========================我不说你也知道我是分割线了吧========================
固定长度字符串数组:赋值快,释放快!
固定长度字符串的处理速度通常慢于可变长度字符串,这是因为所有的VB字符串函数和命令只能识别可变长度字符串.因此,所有固定长度字符串必然被转换为可变长度字符串.
但是,由于固定长度字符串数组占据着一块连续的内存区域,因此在被分配以及释放时,速度明显快于可变长度的数组.比如:在一个Pentium 233MHz机器上,对于一个固定长度为100,000的数组,给其中30个位置分配数值,大约只花费半秒种的时间.而如果是可变长度的数组,同样的操作要耗费8秒之多!后者的删除操作耗时大约0.35秒,但固定长度的数组几乎可以立即"毙命"!如果应用程序中涉及到这么大的一个数组操作,选择固定长度方式数组绝对是确定无疑的了,无论是分配数值,还是释放操作,都可以风驰电掣般完成.
===========================;:P 我又来了=========================================
创建任意长度重复字符串的简洁方法
String$函数只能重复复制单字符(99%的朋友都知道吧),当需要重复复制2个或多个字符时,就需要一个循环.看起来是否很麻烦?
然而,使用以下的函数就能解决这个问题.基本思路是:建立一个空格字符串,其长度为要重复复制的数目,然后替换每一个空格为要复制的字符串:Function ReplicateString(Source As String, Times As Long) As String
ReplicateString = Replace$(Space$(Times), " ", Source)
End Function
复制代码但是请注意:根据字符串的长度以及重复的数目,这个方法也许比传统的循环方法要慢些.
===========================::$ 我又来了=====================================
另辟蹊径处理字符串中的字符:字节数组法
当要处理字符串中的每一个字符时,可以将字符串赋值到一个byte数组中进行操作.要记住:每一个Unicode字符对应双字节.
这种方法通常要快许多,因为节省了大量的Mid$函数操作以及大量的临时字符串空间.下面的代码是统计字符串中空格数目的最快方法Dim b() as Byte, count As Integer
b() = source$
For i = 0 to UBound(b) Step LenB("A")
If b(i) = 32 Then count = count + 1
Next
复制代码请注意上面代码中LenB()函数的特殊用法:在VB4(32位)、VB5和VB6中它返回数值2, 在VB4(16位)中返回数值1.因此,我们就可以使用同一代码段,而无需#If编译指令. (::o 什么?不知道VB456,就当这句话没说)
=================================:hug: 换个马甲[em07] =============================
无闪烁地快速附加字符串到textbox控件
附加文本到TextBox或者RichTextBox控件的通常方法是在当前内容上连接上新的字符串:
Text1.Text = Text1.Text & newString
但还有一个更快的方法,并且会减少连接操作的闪烁感,代码如下:
Text1.SelStart = Len(Text1.Text)
Text1.SelText = newString
精用Boolean表达式让代码减肥
当设置基于表达式结果的Boolean型数值时,要避免使用多余的If/Then/Else语句结果.比如:If SomeVar > SomeOtherVar Then
BoolVal = True
Else
BoolVal = False
End If
复制代码上面这段代码就很烦琐,它们完全可以使用下面的一行代码来替代:BoolVal = (SomeVar > SomeOtherVar)
复制代码括号不是必须的,但可以增加可读性.根据表达式中的操作数不同,后者比前者执行起来大约快50%到85%.后者中的括号对速度没有影响.
有时,使用这个技术实现代码的简练并非很明显.关键是要牢记:所有的比较操作结果或者是0(false),或者是-1(True).所以,下面例子中的2段代码是完全相同的,但是第2段要运行得快些:
1、传统方法:If SomeVar > SomeOtherVar Then
x = x + 1
End If
复制代码2、更简练的方法x = x - (SomeVar > SomeOtherVar)
复制代码----------------------------------------------------------------------------------------------------------------------
用And、Or和Xor来优化表达式
要检测一个整数值的最高有效位是否有数值,通常要使用如下的代码(有二种情况:第一组If判断表明对Integer类型,第二组对Long类型):If intValue And &H8000 Then
' most significant bit is set
End If
If lngValue And &H80000000 Then
' most significant bit is set
End If
复制代码但由于所有的VB变量都是有符号的,因此,最高有效位也是符号位,不管处理什么类型的数值,通过下面的代码就可以实现检测目的:If anyValue < 0 Then
' most significant bit is set
End If
复制代码 '注:上面这段话似乎涉及到数据在内存中的储存表达方式,本人不是太明白,不过下面的代码还是有效的,也都能够理解
另外,要检测2个或者更多个数值的符号,只需要通过一个Bit位与符号位的简单表达式就可以完成.下面是应用这个技术的几段具体代码:1、判断X和Y是否为同符号数值:
If (x < 0 And y < 0) Or (x >= 0 And y >=0) Then ...
' the optimized approach
If (x Xor y) >= 0 Then
2、判断X、Y和Z是否都为正数
If x >= 0 And y >= 0 And z >= 0 Then ...
' the optimized approach
If (x Or y Or z) >= 0 Then ...
3、判断X、Y和Z是否都为负数
If x < 0 And y < 0 And z < 0 Then ...
' the optimized approach
If (x And y And z) < 0 Then ...
4、判断X、Y和Z是否都为0
If x = 0 And y = 0 And z = 0 Then ...
' the optimized approach
If (x Or y Or z) = 0 Then ...
5、判断X、Y和Z是否都不为0
If x = 0 And y = 0 And z = 0 Then ...
' the optimized approach
If (x Or y Or z) = 0 Then ...
复制代码要使用这些来简单化一个复杂的表达式,必须要完全理解boolean型的操作原理.比如,你可能会认为下面的2行代码在功能上是一致的:If x <> 0 And y <> 0 Then
If (x And y) Then ...
复制代码然而我们可以轻易地证明他们是不同的,比如X=3(二进制=0011),Y=4(二进制=0100).不过没有关系,遇到这种情况时,我们可以对上面的代码进行局部优化,就能实现目的.代码如下:If (x <> 0) And y Then ...
复制代码 |
|