Nim icon indicating copy to clipboard operation
Nim copied to clipboard

fixes #20232;indices now use `copyMem` and `moveMem`; much faster slicing and slicing assignments

Open ringabout opened this issue 1 year ago • 6 comments

fixes #20232

import benchy

template `^^`(s, i: untyped): untyped =
  (when i is BackwardsIndex: s.len - int(i) else: int(i))

proc assign1*[T, U: Ordinal](s: var string, x: HSlice[T, U], b: string) =
  var a = s ^^ x.a
  var xb = s ^^ x.b
  var L = (xb) - a + 1
  if L == b.len:
    if L > 0:
      if xb <= s.len:
        when defined(nimSeqsV2):
          prepareMutation(s)
        copyMem(addr s[a], addr b[0], L)
      else:
        raise newException(IndexDefect, "defect")


proc assign2*[T, U: Ordinal](s: var string, x: HSlice[T, U], b: string) =
  var a = s ^^ x.a
  var L = (s ^^ x.b) - a + 1

  if L == b.len:
    if L > 0:
      for i in 0..<L: s[i+a] = b[i]

timeIt "copyMem":
  var s = "abcdefgh"
  for i in 0..1000000:
    assign1(s, 1 .. 3, "xyz")

timeIt "old":
  var s = "abcdefgh"
  for i in 0..1000000:
    assign2(s, 1 .. 3, "xyz")

A simple benchmark for string slice

-d:release

   min time    avg time  std dv   runs name
   0.545 ms    0.603 ms  ±0.017  x1000 copyMem
   1.594 ms    1.754 ms  ±0.256  x1000 old

-d:danger

   0.541 ms    0.591 ms  ±0.021  x1000 copyMem
   0.932 ms    0.957 ms  ±0.040  x1000 old

It uses moveMem for array and seq slice assignment because there is a possibility that the memory overlaps using toOpenArray, for example. I don't see it is probable for strings, isn't it?

ringabout avatar Apr 13 '23 13:04 ringabout