搜寻第一次不为 0 的位置的超快速方法解决方法
搜寻第一次不为 0 的位置的超快速方法
请问 搜寻第一次不为 0 的位置的超快速方法
Dim w As Long
Dim buff As String
buff = String(190000, Chr(0))
p = ((Rnd * 1000) Mod 100) + 1 ' p 是一个不固定的值, 所以无法用 InStrRev() 查找
Mid(buff, 500, 1) = Chr(p)
t = Timer
For w = Len(buff) To 1 Step -1
If Asc(Mid(buff, w)) <> 0 Then
buff = Left(buff, w)
Exit For
End If
Next
Debug.Print Timer - t
' 因为 buff 太长, 导致用 For .... Loop 太慢
不知有无 WinAPI 或 类似 2分搜寻的 code 可以办到大幅加快速度
------解决方案--------------------
怎么我觉得用这个处理很快?你的代码要7秒左右,这个代码不要一秒.
请问 搜寻第一次不为 0 的位置的超快速方法
Dim w As Long
Dim buff As String
buff = String(190000, Chr(0))
p = ((Rnd * 1000) Mod 100) + 1 ' p 是一个不固定的值, 所以无法用 InStrRev() 查找
Mid(buff, 500, 1) = Chr(p)
t = Timer
For w = Len(buff) To 1 Step -1
If Asc(Mid(buff, w)) <> 0 Then
buff = Left(buff, w)
Exit For
End If
Next
Debug.Print Timer - t
' 因为 buff 太长, 导致用 For .... Loop 太慢
不知有无 WinAPI 或 类似 2分搜寻的 code 可以办到大幅加快速度
------解决方案--------------------
怎么我觉得用这个处理很快?你的代码要7秒左右,这个代码不要一秒.
- VB code
Private Sub Form_Load() Dim w As Long Dim buff As String Randomize buff = String(190000, Chr(0)) p = ((Rnd * 1000) Mod 100) + 1 ' p 是一个不固定的值, 所以无法用 InStrRev() 查找 Mid(buff, 189999, 1) = Chr(p) t = Timer 'For w = Len(buff) To 1 Step -1 'If Asc(Mid(buff, w)) <> 0 Then 'buff = Left(buff, w) 'Exit For 'End If 'Next For w = 1 To 190000 If Mid(buff, w, 1) <> Chr(0) Then Debug.Print w: Exit For Next Debug.Print Timer - t ' 因为 buff 太长, 导致用 For .... Loop 太慢 End Sub
------解决方案--------------------
VB中字符串反正讲不清,其实这个直接访问内存最快。
- VB code
Private Type SafeArrayBound Elements As Long lLbound As Long End Type Private Type SAFEARRAY Dimension As Integer Features As Integer Element As Long Locks As Long Pointer As Long Bounds As SafeArrayBound End Type Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDst As Any, lpSrc As Any, ByVal ByteLength As Long) Private Declare Function GetTickCount Lib "kernel32" () As Long Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (ByRef Ptr() As Any) As Long Private Sub Command1_Click() Dim Sa As SAFEARRAY, StrData() As Byte Dim Str As String, Length As Long Dim I As Long, T As Double Str = String(190000, Chr(0)) Length = Len(Str) I = ((Rnd * 1000) Mod 100) + 1 Mid(Str, 500, 1) = Chr(I) With Sa .Element = 1 .Dimension = 1 .Bounds.Elements = Length .Pointer = StrPtr(Str) End With CopyMemory ByVal VarPtrArray(StrData()), VarPtr(Sa), 4 T = Timer For I = Length - 1 To 0 Step -1 If StrData(I) <> 0 Then Debug.Print I Exit For End If Next CopyMemory ByVal VarPtrArray(StrData()), 0&, 4 End Sub