Faster readStr() (#14099)

* Faster readStr()

* https://github.com/nim-lang/Nim/issues/13857

* Add .since annotation and add to changelog

* Private, un-sinced proc for csource bootstrapping
This commit is contained in:
Christopher Dunn
2020-04-25 13:19:11 -05:00
committed by GitHub
parent 018e297d66
commit caf30e7cb5
2 changed files with 25 additions and 6 deletions

View File

@@ -37,6 +37,9 @@
and this can now throw in edge cases where `getCurrentDir` throws.
`relativePath` also now works for js with `-d:nodejs`.
- Added `streams.readStr` and `streams.peekStr` overloads to
accept an existing string to modify, which avoids memory
allocations, similar to `streams.readLine` (#13857).
## Language changes
- In newruntime it is now allowed to assign discriminator field without restrictions as long as case object doesn't have custom destructor. Discriminator value doesn't have to be a constant either. If you have custom destructor for case object and you do want to freely assign discriminator fields, it is recommended to refactor object into 2 objects like this:

View File

@@ -841,6 +841,16 @@ proc peekFloat64*(s: Stream): float64 =
peek(s, result)
proc readStrPrivate(s: Stream, length: int, str: var TaintedString) =
if length > len(str): setLen(str.string, length)
var L = readData(s, cstring(str), length)
if L != len(str): setLen(str.string, L)
proc readStr*(s: Stream, length: int, str: var TaintedString) {.since: (1, 3).} =
## Reads a string of length `length` from the stream `s`. Raises `IOError` if
## an error occurred.
readStrPrivate(s, length, str)
proc readStr*(s: Stream, length: int): TaintedString =
## Reads a string of length `length` from the stream `s`. Raises `IOError` if
## an error occurred.
@@ -851,10 +861,18 @@ proc readStr*(s: Stream, length: int): TaintedString =
doAssert strm.readStr(2) == "e"
doAssert strm.readStr(2) == ""
strm.close()
result = newString(length).TaintedString
var L = readData(s, cstring(result), length)
if L != length: setLen(result.string, L)
readStrPrivate(s, length, result)
proc peekStrPrivate(s: Stream, length: int, str: var TaintedString) =
if length > len(str): setLen(str.string, length)
var L = peekData(s, cstring(str), length)
if L != len(str): setLen(str.string, L)
proc peekStr*(s: Stream, length: int, str: var TaintedString) {.since: (1, 3).} =
## Peeks a string of length `length` from the stream `s`. Raises `IOError` if
## an error occurred.
peekStrPrivate(s, length, str)
proc peekStr*(s: Stream, length: int): TaintedString =
## Peeks a string of length `length` from the stream `s`. Raises `IOError` if
@@ -867,10 +885,8 @@ proc peekStr*(s: Stream, length: int): TaintedString =
doAssert strm.readStr(2) == "ab"
doAssert strm.peekStr(2) == "cd"
strm.close()
result = newString(length).TaintedString
var L = peekData(s, cstring(result), length)
if L != length: setLen(result.string, L)
peekStrPrivate(s, length, result)
proc readLine*(s: Stream, line: var TaintedString): bool =
## Reads a line of text from the stream `s` into `line`. `line` must not be