High performance Replace function as an alternative to the plain VBA.Replace function
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 45/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bastante claro
- Estado de actividad
- Estancado
- Área
- performance, tooling
Línea de trabajo
Start by reviewing the Replace08 and Replace08Bin implementations in the issue, including the included Replace08_test benchmark. Compare its behavior with VBA.Replace across the documented parameters and determine how it would fit the project's existing Replace call sites. Done means a tested, integrated alternative with demonstrated performance improvement and compatible replacement behavior.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Hi @sancarn
In your project use many times call Replace function. The original Replace function, really slow.
I found the code below used by wqweto in some project shared by him, I trusted and tested, and the result is unbelievable that the performance is many times better than the original VBA.Replace function.
The real creator is Jost Schwider based on the comment in the code by Jost Schwider, [email protected], 20001218
You can test to take advantage of the Replace function in your project
Option Explicit
#If VBA7 = 0 Then
Private Enum LongPtr
[_]
End Enum
#End If
#If VBA7 Then
Private Declare PtrSafe Function SysAllocStringByteLen Lib "OleAut32" (ByVal olestr As LongPtr, ByVal BLen As Long) As LongPtr
Private Declare PtrSafe Sub RtlMoveMemory Lib "kernel32" (dst As Any, src As Any, ByVal nBytes As LongPtr)
Private Declare PtrSafe Sub RtlZeroMemory Lib "kernel32" (dst As Any, ByVal nBytes As LongPtr)
#Else
Private Declare Function SysAllocStringByteLen Lib "oleaut32" (ByVal olestr As Long, ByVal BLen As Long) As Long
Private Declare Sub RtlMoveMemory Lib "kernel32" (dst As Any, src As Any, ByVal nBytes&)
Private Declare Sub RtlZeroMemory Lib "kernel32" (dst As Any, ByVal nBytes&)
#End If
Private Const FADF_AUTO As Long = &H1 '// Array is allocated on the stack.
Private Const FADF_FIXEDSIZE As Long = &H10 '// Array may not be resized or reallocated.
Private Sub Replace08_test()
Dim s$, t!
s = String(10000000, "a")
t = Timer
Debug.Print Replace08(s, "aaa", "")
Debug.Print "Replace08: "; Round(Timer - t, 5)
t = Timer
Debug.Print Replace$(s, "aaa", "")
Debug.Print "Replace: "; Round(Timer - t, 5)
End Sub
Public Function Replace08(ByVal Text As String, _
ByVal sOld As String, ByVal sNew As String, _
Optional ByVal start As Long = 1, _
Optional ByVal count As Long = 2147483647, _
Optional ByVal compare As VbCompareMethod = vbBinaryCompare _
) As String
' by Jost Schwider, [email protected], 20001218
If LenB(sOld) Then
If compare = vbBinaryCompare Then
Replace08Bin Replace08, Text, Text, sOld, sNew, start, count
Else
Replace08Bin Replace08, Text, LCase$(Text), LCase$(sOld), sNew, start, count
End If
Else 'Suchstring ist leer:
Replace08 = Text
End If
End Function
Private Static Sub Replace08Bin(ByRef result As String, _
ByRef Text As String, ByRef Search As String, _
ByRef sOld As String, ByRef sNew As String, _
ByVal start As Long, ByVal count As Long)
' by Jost Schwider, [email protected], 20001218
Dim TextLen As Long, OldLen As Long, NewLen As Long, ReadPos As Long
Dim WritePos As Long, CopyLen As Long, buffer As String, BufferLen As Long, BufferPosNew As Long, BufferPosNext As Long
'Ersten Treffer bestimmen:
If start < 2 Then
start = InStrB(Search, sOld)
Else
start = InStrB(start + start - 1, Search, sOld)
End If
If start Then
OldLen = LenB(sOld)
NewLen = LenB(sNew)
Select Case NewLen
Case OldLen 'einfaches Überschreiben:
result = Text
For count = 1 To count
MidB$(result, start) = sNew
start = InStrB(start + OldLen, Search, sOld)
If start = 0 Then Exit Sub
Next count
Case 0 'nur Entfernen:
'Buffer initialisieren:
TextLen = LenB(Text)
If TextLen > BufferLen Then
buffer = Text
BufferLen = TextLen
End If
'Ausschneiden:
ReadPos = 1
WritePos = 1
For count = 1 To count
CopyLen = start - ReadPos
If CopyLen Then
MidB$(buffer, WritePos) = MidB$(Text, ReadPos, CopyLen)
WritePos = WritePos + CopyLen
End If
ReadPos = start + OldLen
start = InStrB(ReadPos, Search, sOld)
If start = 0 Then Exit For
Next count
'Ergebnis zusammenbauen:
If ReadPos > TextLen Then
result = LeftB$(buffer, WritePos - 1)
Else
MidB$(buffer, WritePos) = MidB$(Text, ReadPos)
result = LeftB$(buffer, WritePos + TextLen - ReadPos)
End If
Exit Sub
Case Is < OldLen 'Ergebnis wird kürzer:
'Buffer initialisieren:
TextLen = LenB(Text)
If TextLen > BufferLen Then
buffer = Text
BufferLen = TextLen
End If
'Ersetzen:
ReadPos = 1
WritePos = 1
For count = 1 To count
CopyLen = start - ReadPos
If CopyLen Then
BufferPosNew = WritePos + CopyLen
MidB$(buffer, WritePos) = MidB$(Text, ReadPos, CopyLen)
MidB$(buffer, BufferPosNew) = sNew
WritePos = BufferPosNew + NewLen
Else
MidB$(buffer, WritePos) = sNew
WritePos = WritePos + NewLen
End If
ReadPos = start + OldLen
start = InStrB(ReadPos, Search, sOld)
If start = 0 Then Exit For
Next count
'Ergebnis zusammenbauen:
If ReadPos > TextLen Then
result = LeftB$(buffer, WritePos - 1)
Else
MidB$(buffer, WritePos) = MidB$(Text, ReadPos)
result = LeftB$(buffer, WritePos + LenB(Text) - ReadPos)
End If
Exit Sub
Case Else 'Ergebnis wird länger:
'Buffer initialisieren:
TextLen = LenB(Text)
BufferPosNew = TextLen + NewLen
If BufferPosNew > BufferLen Then
buffer = Space$(BufferPosNew)
BufferLen = LenB(buffer)
End If
'Ersetzung:
ReadPos = 1
WritePos = 1
For count = 1 To count
CopyLen = start - ReadPos
If CopyLen Then
'Positionen berechnen:
BufferPosNew = WritePos + CopyLen
BufferPosNext = BufferPosNew + NewLen
'Ggf. Buffer vergrößern:
If BufferPosNext > BufferLen Then
buffer = buffer & Space$(BufferPosNext)
BufferLen = LenB(buffer)
End If
'String "patchen":
MidB$(buffer, WritePos) = MidB$(Text, ReadPos, CopyLen)
MidB$(buffer, BufferPosNew) = sNew
WritePos = BufferPosNext
Else
'Position bestimmen:
BufferPosNext = WritePos + NewLen
'Ggf. Buffer vergrößern:
If BufferPosNext > BufferLen Then
buffer = buffer & Space$(BufferPosNext)
BufferLen = LenB(buffer)
End If
'String "patchen":
MidB$(buffer, WritePos) = sNew
WritePos = BufferPosNext
End If
ReadPos = start + OldLen
start = InStrB(ReadPos, Search, sOld)
If start = 0 Then Exit For
Next count
'Ergebnis zusammenbauen:
If ReadPos > TextLen Then
result = LeftB$(buffer, WritePos - 1)
Else
BufferPosNext = WritePos + TextLen - ReadPos
If BufferPosNext < BufferLen Then
MidB$(buffer, WritePos) = MidB$(Text, ReadPos)
result = LeftB$(buffer, BufferPosNext)
Else
result = LeftB$(buffer, WritePos - 1) & MidB$(Text, ReadPos)
End If
End If
Exit Sub
End Select
Else 'Kein Treffer:
result = Text
End If
End Sub
- Lenguaje dominante
- VBA
- Estrellas
- 412
- Forks
- 70
- Merge medio
- 20 h 38 min
- PR fusionados (30 d)
- 18
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de sancarn/stdVBA
-
Dificultad 4/5 3-5 días Aptitud para principiantes 45/100
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
sancarn/stdVBA#138 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
enhancement lib-stdArray
Dificultad 4/5 3-5 días Aptitud para principiantes 25/100
Los mantenedores suelen responder en 1 día
-
`stdUIElement` megathreadAbiertoenhancement megathread
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
Los mantenedores suelen responder en 1 día
-
`stdJSON` parse performanceAbiertoenhancement lib-stdJSON
Dificultad 5/5 Más de una semana Aptitud para principiantes 30/100
sancarn/stdVBA#82 · 1 reacción ·
Los mantenedores suelen responder en 1 día
Todos los issues de sancarn/stdVBA
Issues similares
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 80/100
Los mantenedores suelen responder en 1 día
-
Performance regression in getComputeStyle()Posiblemente ocupada @iquadrat la tomó hoy. Abiertoquestion
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
capricorn86/happy-dom#2568 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
superplanehq/superplane#9117 ·
Los mantenedores suelen responder en 1 día
-
Load geotiff on demandAbiertoenhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
Deltares/webgl-streamline-visualizer#82 ·
Los mantenedores suelen responder en 1 día
-
[Perf] Default --vllm-watermark 0.05 for rollouts (hybrid models re-preempt under KV pressure)Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
vllm-project/vime#508 ·
Los mantenedores suelen responder en 4 días