用下面的语句,会造成假死
dim i as long
dim j as long
dim str as stringfor i=0 to 60000
for j=0 to 10
str=str & "XX" & chr(9)
next j
str=str & chr(13)
next i
如何提高速度?
dim i as long
dim j as long
dim str as stringfor i=0 to 60000
for j=0 to 10
str=str & "XX" & chr(9)
next j
str=str & chr(13)
next i
如何提高速度?
Dim i As Long
Dim j As Long
Dim k As Long
Dim str As String
str = String(3000000, 0)
k = 1
For i = 0 To 6000
For j = 0 To 10
Mid$(str, k) = "XX" & Chr(9)
k = k + 3
Next j
Mid$(str, k) = Chr(13)
k = k + 1
Next i
str = Left$(str, k - 1)
Debug.Print Len(str), k
Dim myString As String, myByte(63989) As ByteMe.MousePointer = vbHourGlassFor i = 0 To 9
n = i * 3
myByte(n) = 88 'Asc("X")
myByte(n + 1) = 88 'Asc("X")
myByte(n + 2) = IIf(i < 9, 9, 13)
Next iFor i = 0 To 63989 Step 30
DoEvents
CopyMemory myByte(i), myByte(0), 30
Next imyString = StrConv(myByte, vbUnicode)
Me.MousePointer = vbNormal
Dim y,za = "xx" & Chr(9)
y = String(11, "a")
y = Replace(y, "a", a)
b = y & Chr(13)
z = String(60000, "b")
z = Replace(z, "b", b)
Dim i As Long
Dim j As Long
Dim istr As String
Form1.Show
istr = ""
For j = 0 To 10
istr = istr & "XX" & Chr(9)
Next j
MsgBox istr
For i = 0 To 60000 Step 11
istr = istr & Chr(13)
Next i
Print istrEnd Sub
假定你的XX放在一个数组 bytSource() 中Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Dim myString As String, myByte(63989) As Byte, tmp(29) As Byte
Dim i As Long, j As Long, k As LongMe.MousePointer = vbHourGlass
'预先填充制表符和回车符
For i = 0 To 9
n = i * 3
tmp(n + 2) = IIf(i < 9, 9, 13)
Next i k = 0
For i = 0 To 63989 Step 30
DoEvents
'填充数据到记录
For j = 0 To 9
n = j * 3
tmp(n) = bytSource(k)
tmp(n + 1) = bytSource(k + 1)
k = k + 2
Next j
'复制记录
CopyMemory myByte(i), tmp(0), 30
Next i '转换为字符串
myString = StrConv(myByte, vbUnicode)
Me.MousePointer = vbNormal
Dim j As Long
Dim s As String
Dim ss As String
For j = 1 To 10
s = s & "XX" & Chr$(9)
Next j
s = s & vbCrLf
ss = s
For i = 1 To 10
ss = ss & ss
Next i
Debug.Print ss
End Sub
;用字符串自己叠加。
这是VB中连接100W个字符“a”最快的代码:先定义一个类型库,在里面声明SysAllocStringByteLen这个API
module OleAut32
{
[entry("SysAllocStringByteLen")]
BSTR SysAllocStringByteLen ([in] long lpUnicodeString, [in] DWORD Length);
}
如果嫌麻烦的话就直接用Declare声明,但效率会下降。Dim str(1000000) As StringOption ExplicitPrivate Declare Function SysAllocStringByteLen Lib "OleAut32" (ByVal lpUnicodeString As Long, ByVal Length As Long) As StringPrivate Sub Form_Load()
Const SIZE = 1000000 Dim str As String
Dim buf(SIZE - 1) As Byte
Dim i As Long
For i = 0 To SIZE - 1
buf(i) = 97
Next str = SysAllocStringByteLen(VarPtr(buf(0)), SIZE) MsgBox Len(str)
End Sub
Private Const StrUbound As Long = 600000 '60W个字符串Private Sub Command1_Click()
Dim sA As String, sB(StrUbound) As String
Dim I As Long, J As Long
For I = 0 To StrUbound '初始化字符串
sB(I) = csA
Next
MsgBox "开始"
J = GetTickCount
sA = Join(sB, vbCrLf) '用回车换行符来连接
MsgBox "结束,时间=" & GetTickCount - J & "ms"
MsgBox "写入1.txt"
Open "1.txt" For Binary As #1
Put 1, , sA
Close #1
MsgBox "结束写入"
End Sub
在我这里,60W个字符串的连接花了140毫秒,算快的了,保存得到一个16M的TXT;当改成600W时,花了1034毫秒,不过在保存时就溢出了~~~至于6000W时.......直接就溢出.....这个JOIN很强......之前不知道.....在僵哥那里才知道的,很好很强大吧......VB6里面不知道还有多少不知道的招呢......?
Option ExplicitPrivate Const PARTS_COUNT As Long = 100
Private aParts(PARTS_COUNT - 1) As StringSub Main()
PrepareParts
Test1
Test2
End Sub'预先准备不定长字符串,减少对拼接速度的影响。可以认为所有的拼接内容是随机的。
Sub PrepareParts()
Dim i As Long
Randomize
For i = 0 To PARTS_COUNT - 1
aParts(i) = CStr(Rnd())
Next
Debug.Print Len(Join(aParts, "")), Join(aParts, "")
End SubSub Test1()
Dim fStart As Single, fFinish As Single
fStart = Timer()
'---------------
Const GROW_SIZE = &H100000 '=1024*1024 = 1M
Dim i As Long
Dim j As Long
Dim l As Long 'Index of aParts
Dim lLen As Long '=Len(aParts(l))
Dim k As Long
Dim kMax As Long
Dim str As String kMax = GROW_SIZE
str = String(kMax, 0) l = 0
k = 1
For i = 0 To 60000
For j = 0 To 10
lLen = Len(aParts(l))
If (k + lLen + 1) > kMax Then '<-(1)
kMax = kMax + GROW_SIZE
str = str & String(kMax, 0)
End If
Mid$(str, k) = aParts(l) & vbTab l = (l + 1) Mod PARTS_COUNT
k = k + lLen + 1
Next j
Mid$(str, k) = vbLf '在 (1) 的增长中多留了一个字符,这里保证够用
k = k + 1
Next i
str = Left$(str, k - 1) '---------------
fFinish = Timer()
Debug.Print "Test1()", FormatNumber(fFinish - fStart, 3), Len(str)
End SubSub Test2()
Dim fStart As Single, fFinish As Single
fStart = Timer()
'--------------- Dim str As String
Dim a() As String
Dim i As Long
Dim j As Long
Dim l As Long ReDim a(60001 * 11 - 1)
For i = 0 To 60000
For j = 0 To 10
a(l) = aParts(l Mod PARTS_COUNT) & vbTab
l = l + 1
Next
a(l - 1) = a(l - 1) & vbCr
Next
str = Join(a, vbNullString) '---------------
fFinish = Timer()
Debug.Print "Test2()", FormatNumber(fFinish - fStart, 3), Len(str)
End Sub
哈哈~~最快的代码应该是这样:Dim str As String
str = String(SIZE, "a")
------------------------
应该使用数组来操作,就像处理C字符串一样dim i as long
dim j as long
dim str(60000,11) as string
dim str2 as stringfor i=0 to 60000
for j=0 to 10
str(i,j) = "XX" & chr(9)
next j
str(i,11) = chr(13)
next i str2=join(str,"")
1. 用API:
比如定义一个byte数组,然后填充字符,然后调用SysAllocStringByteLen,系统会申请一段全局内存,
然后,系统把byte数组拷贝到那段内存,返回一个指针(在vb6里是string) * 花费: 用户总体拷贝1次(一个一个地赋值给byte),系统1次大拷贝2. 用join:
定义一批string数组,然后你填充字符,然后调用join,系统拷贝这批string数组到另一个连续的byte数组,
那么byte数组=string1 + string2 + .... ,然后像1那样处理 * 花费: 用户拷贝1次引起系统拷贝多次,像:s(i) = newString ,系统要对s(i)重新分配,然后拷贝newstring给s(i),然后join(s)时,系统会按api方法处理(像方法1那样),所以系统要拷贝2n+1次(2n次小,一次大)3. 直接连接
花费: 用户拷贝n次,因为像:s(i) = s(i) & newstring , 所以系统每连接一次就要多拷贝1次,1+2+3+...n,
所以newstring被拷贝n!次,总拷贝数为恐怖次,而且会造成64k缓冲溢出的危险4. 用copymemory:
这种方法可能最快,比join快在:没有每次对s(i)进行重分配,但会给StrConv拖慢(此函数又总体的拷贝了一次)5. str = String(SIZE, "a")我怀疑是最快的,如果vb6优化的话!!!
因为:如果直接在申请的byte内存里填充形如:0,0,0,0,0,97,0,97,0,97....,0,0 (unicode字符),
然后填充一个bstr前缀,不就是一个字符串了吗?? 那么要彻底了解OleAut32!
更正: 5. str = String(SIZE, "a ")我怀疑是最快的,如果vb6优化的话!!!
因为:如果直接在申请的byte内存里填充形如:0,0,0,0,97,0,97,0,97,0....,0,0 (unicode字符),
然后填充一个bstr前缀,不就是一个字符串了吗?? 那么要彻底了解OleAut32! 6. mid方法:
应该比join快,因为mid少一次拷贝(已经预先分配空间),join连接时多拷贝一次
mid就像copymeory dim b as byte
dim i as integer
b = 97
i = &H6211
s = "abcdefg"
mid(s,3,1) = "a"
'或者:copymeory byval strptr(s) + 4, b, 1 'abadefg
' copymeory byval strptr(s) + 4, i, 2 'ab我defg msgbox s
Dim i As Long
Dim j As Long
Dim str As String
Dim strx As String
Dim ie As Long
Dim iex As Longie = 60000
iex = Sqr(60000)For i = 0 To ie
For j = 0 To 10
strx = strx & "XX" & Chr(9)
Next j
strx = strx & Chr(13)
If Not CBool(i Mod iex) Then
strx = ""
str = str & strx
End If
Next i
str = str & strx
Dim i As Long
Dim j As Long
Dim str As String
Dim strx As String
Dim ie As Long
Dim iex As Long ie = 60000
iex = Sqr(60000) For i = 0 To ie
For j = 0 To 10
strx = strx & "XX" & Chr(9)
Next j
strx = strx & Chr(13)
If Not CBool(i Mod iex) Then
str = str & strx
strx = ""
End If
Next i
str = str & strx
MsgBox Len(str)
小仙妹是VB的天才,恰比当年的比尔·盖茨。希望小仙妹学好汇编,写个操作系统(暂且定名为“Kitesoft Girl”操作系统),再写个在“Kitesoft Girl”下的编译器(暂且定名为“Kitesoft C”),当年比尔·盖茨也只是拿着DOS和BASIC走过来的,我相信以小仙妹的智慧,只要把汇编学好,世界就是你的了!本董是一个艺术家!因为,吹牛是一种艺术!