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:
parent
bd7807de4c
commit
643dbc743b
2 changed files with 32 additions and 4 deletions
|
|
@ -67,6 +67,11 @@ aiming for your debugging pleasure. With `-d:release` some checks are
|
||||||
`turned off and optimizations are turned on
|
`turned off and optimizations are turned on
|
||||||
<nimc.html#compiler-usage-compileminustime-symbols>`_.
|
<nimc.html#compiler-usage-compileminustime-symbols>`_.
|
||||||
|
|
||||||
|
For benchmarking or production code, use the `-d:release` switch.
|
||||||
|
For comparing the performance with unsafe languages like C, use the `-d:danger` switch
|
||||||
|
in order to get meaningful, comparable results. Otherwise Nim might be handicapped
|
||||||
|
by checks that are **not even available** for C.
|
||||||
|
|
||||||
Though it should be pretty obvious what the program does, I will explain the
|
Though it should be pretty obvious what the program does, I will explain the
|
||||||
syntax: statements which are not indented are executed when the program
|
syntax: statements which are not indented are executed when the program
|
||||||
starts. Indentation is Nim's way of grouping statements. Indentation is
|
starts. Indentation is Nim's way of grouping statements. Indentation is
|
||||||
|
|
@ -626,7 +631,7 @@ Some terminology: in the example `question` is called a (formal) *parameter*,
|
||||||
Result variable
|
Result variable
|
||||||
---------------
|
---------------
|
||||||
A procedure that returns a value has an implicit `result` variable declared
|
A procedure that returns a value has an implicit `result` variable declared
|
||||||
that represents the return value. A `return` statement with no expression is
|
that represents the return value. A `return` statement with no expression is
|
||||||
shorthand for `return result`. The `result` value is always returned
|
shorthand for `return result`. The `result` value is always returned
|
||||||
automatically at the end of a procedure if there is no `return` statement at
|
automatically at the end of a procedure if there is no `return` statement at
|
||||||
the exit.
|
the exit.
|
||||||
|
|
|
||||||
|
|
@ -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)):
|
when not (defined(js) or defined(nimdoc) or defined(nimscript)):
|
||||||
func c_memchr(cstr: pointer, c: char, n: csize_t): pointer {.
|
func c_memchr(cstr: pointer, c: char, n: csize_t): pointer {.
|
||||||
importc: "memchr", header: "<string.h>".}
|
importc: "memchr", header: "<string.h>".}
|
||||||
|
func c_strstr(haystack, needle: cstring): cstring {.
|
||||||
|
importc: "strstr", header: "<string.h>".}
|
||||||
|
|
||||||
const hasCStringBuiltin = true
|
const hasCStringBuiltin = true
|
||||||
else:
|
else:
|
||||||
const hasCStringBuiltin = false
|
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>`_
|
## * `replace func<#replace,string,string,string>`_
|
||||||
if sub.len > s.len: return -1
|
if sub.len > s.len: return -1
|
||||||
if sub.len == 1: return find(s, sub[0], start, last)
|
if sub.len == 1: return find(s, sub[0], start, last)
|
||||||
var a {.noinit.}: SkipTable
|
|
||||||
initSkipTable(a, sub)
|
template useSkipTable {.dirty.} =
|
||||||
result = find(a, s, sub, start, last)
|
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,
|
func rfind*(s: string, sub: char, start: Natural = 0, last = -1): int {.rtl,
|
||||||
extern: "nsuRFindChar".} =
|
extern: "nsuRFindChar".} =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue