use strstr for a faster find implementation (#17672)

* use strstr for a faster find implementation
* stress the -d:release and -d:danger switches
This commit is contained in:
Andreas Rumpf
2021-04-08 00:54:47 +02:00
committed by GitHub
parent bd7807de4c
commit 643dbc743b
2 changed files with 32 additions and 4 deletions

View File

@@ -1826,6 +1826,9 @@ func find*(a: SkipTable, s, sub: string, start: Natural = 0, last = 0): int {.
when not (defined(js) or defined(nimdoc) or defined(nimscript)):
func c_memchr(cstr: pointer, c: char, n: csize_t): pointer {.
importc: "memchr", header: "<string.h>".}
func c_strstr(haystack, needle: cstring): cstring {.
importc: "strstr", header: "<string.h>".}
const hasCStringBuiltin = true
else:
const hasCStringBuiltin = false
@@ -1889,9 +1892,29 @@ func find*(s, sub: string, start: Natural = 0, last = 0): int {.rtl,
## * `replace func<#replace,string,string,string>`_
if sub.len > s.len: return -1
if sub.len == 1: return find(s, sub[0], start, last)
var a {.noinit.}: SkipTable
initSkipTable(a, sub)
result = find(a, s, sub, start, last)
template useSkipTable {.dirty.} =
var a {.noinit.}: SkipTable
initSkipTable(a, sub)
result = find(a, s, sub, start, last)
when not hasCStringBuiltin:
useSkipTable()
else:
when nimvm:
useSkipTable()
else:
when hasCStringBuiltin:
if last == 0 and s.len > start:
let found = c_strstr(s[start].unsafeAddr, sub)
if not found.isNil:
result = cast[ByteAddress](found) -% cast[ByteAddress](s.cstring)
else:
result = -1
else:
useSkipTable()
else:
useSkipTable()
func rfind*(s: string, sub: char, start: Natural = 0, last = -1): int {.rtl,
extern: "nsuRFindChar".} =