搜寻第一次不为 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秒左右,这个代码不要一秒.

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