Skip to content

Commit c5594f8

Browse files
committed
improve perf
1 parent ed1731d commit c5594f8

File tree

4 files changed

+28
-12
lines changed

4 files changed

+28
-12
lines changed

src/nregex.nim

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,10 @@ func find*(
241241
var i = start
242242
var c: Rune
243243
while i < len(s):
244-
result = matchImpl(s, pattern, m, {mfLongestMatch}, i)
244+
result = matchImpl(s, pattern, m, {mfShortestMatch, mfNoCaptures}, i)
245245
if result:
246+
result = matchImpl(s, pattern, m, {mfLongestMatch}, i)
247+
doAssert result
246248
break
247249
fastRuneAt(s, i, c, true)
248250

src/nregex/dfamacro.nim

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,13 +303,21 @@ func matchImpl*(
303303
qt = q
304304
i = start
305305
iPrev = start
306+
# workaround for VM registry limitation
307+
const
308+
tzLen = regex.transitions.z.len
309+
groupTransitionsLen = regex.groupsCount * 2
310+
noCaptures = mfNoCaptures in flags
306311
# workaround for https://github.com/nim-lang/Nim/issues/13252
307312
const
308313
reFlags = regex.flags
309-
hasTransionsZ = regex.transitions.z.len > 0
314+
canSkipTransitionsZ = noCaptures and
315+
groupTransitionsLen == tzLen
316+
hasTransitionsZ = tzLen > 0 and
317+
not canSkipTransitionsZ
310318
groupCount {.used.} = regex.groupsCount
311319
namedGroups {.used.} = regex.namedGroups
312-
when hasTransionsZ:
320+
when hasTransitionsZ:
313321
var
314322
smA = newSubmatches()
315323
smB = newSubmatches()
@@ -329,12 +337,12 @@ func matchImpl*(
329337
genSymMatchTable(q, qt, c.int32, regex)
330338
if (q == -1'i32).unlikely:
331339
return
332-
when hasTransionsZ:
340+
when hasTransitionsZ:
333341
submatch(smA, smB, capts, regex, iPrev, qt, cPrev, c.int32)
334342
iPrev = i
335343
cPrev = c.int32
336344
genEoeTable(result, q, qt, regex)
337-
when hasTransionsZ:
345+
when hasTransitionsZ:
338346
if not result:
339347
return
340348
# XXX lighter submatchEoe

src/nregex/dfamatch.nim

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ template longestMatchEnter(): untyped {.dirty.} =
200200
if symEoe in regex.dfa.table[q]:
201201
matchedLong = true
202202
iPrevLong = iPrev
203-
if regex.transitions.z.len > 0:
203+
if hasTransitionsZ:
204204
submatch(
205205
smA, smB, capts, regex.transitions,
206206
regex.dfa.cs[regex.dfa.closures[q][symEoe]], iPrev, cPrev, c.int32)
@@ -210,7 +210,7 @@ template longestMatchEnter(): untyped {.dirty.} =
210210

211211
template longestMatchExit(): untyped {.dirty.} =
212212
result = matchedLong
213-
if regex.transitions.z.len > 0:
213+
if hasTransitionsZ:
214214
constructSubmatches(m.captures, capts, captLong, regex.groupsCount)
215215
if regex.namedGroups.len > 0:
216216
m.namedGroups = regex.namedGroups
@@ -219,7 +219,7 @@ template longestMatchExit(): untyped {.dirty.} =
219219

220220
template shortestMatch(): untyped {.dirty.} =
221221
if symEoe in regex.dfa.table[q]:
222-
if regex.transitions.z.len > 0:
222+
if hasTransitionsZ:
223223
submatch(
224224
smA, smB, capts, regex.transitions,
225225
regex.dfa.cs[regex.dfa.closures[q][symEoe]], iPrev, cPrev, c.int32)
@@ -241,7 +241,12 @@ func matchImpl*(
241241
#echo dfa
242242
m.clear()
243243
result = false
244-
let asciiMode = reAscii in regex.flags
244+
let
245+
asciiMode = reAscii in regex.flags
246+
canSkipTransitionsZ = mfNoCaptures in flags and
247+
regex.groupsCount * 2 == regex.transitions.z.len
248+
hasTransitionsZ = regex.transitions.z.len > 0 and
249+
not canSkipTransitionsZ
245250
var
246251
smA: Submatches
247252
smB: Submatches
@@ -257,7 +262,7 @@ func matchImpl*(
257262
matchedLong {.used.} = false
258263
captLong {.used.} = -1
259264
iPrevLong {.used.} = start
260-
if regex.transitions.z.len > 0:
265+
if hasTransitionsZ:
261266
smA = newSubmatches()
262267
smB = newSubmatches()
263268
smA.add((0'i16, -1'i32))
@@ -283,7 +288,7 @@ func matchImpl*(
283288
longestMatchExit()
284289
else:
285290
return
286-
if regex.transitions.z.len > 0:
291+
if hasTransitionsZ:
287292
submatch(
288293
smA, smB, capts, regex.transitions,
289294
regex.dfa.cs[regex.dfa.closures[q][cSym]], iPrev, cPrev, c.int32)
@@ -296,7 +301,7 @@ func matchImpl*(
296301
when mfLongestMatch in flags:
297302
longestMatchExit()
298303
return
299-
if regex.transitions.z.len > 0:
304+
if hasTransitionsZ:
300305
submatch(
301306
smA, smB, capts, regex.transitions,
302307
regex.dfa.cs[regex.dfa.closures[q][symEoe]], iPrev, cPrev, -1'i32)

src/nregex/nfa.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ type
209209
allZ*: TransitionsAll
210210
z*: ZclosureStates
211211

212+
# XXX do not add char classes transitions \w, \d, etc in ascii mode
212213
func eRemoval(
213214
eNfa: seq[Node],
214215
transitions: var Transitions

0 commit comments

Comments
 (0)