exploit nil seqs for performance (#8688)
* changes $ for seqs to never produce 'nil' * exploit the fact that empty seqs don't have to allocate in the code generator
This commit is contained in:
parent
f87a91a3ec
commit
2def616069
6 changed files with 23 additions and 20 deletions
|
|
@ -1176,7 +1176,7 @@ proc genNew(p: BProc, e: PNode) =
|
||||||
rawGenNew(p, a, nil)
|
rawGenNew(p, a, nil)
|
||||||
gcUsage(p.config, e)
|
gcUsage(p.config, e)
|
||||||
|
|
||||||
proc genNewSeqAux(p: BProc, dest: TLoc, length: Rope) =
|
proc genNewSeqAux(p: BProc, dest: TLoc, length: Rope; lenIsZero: bool) =
|
||||||
let seqtype = skipTypes(dest.t, abstractVarRange)
|
let seqtype = skipTypes(dest.t, abstractVarRange)
|
||||||
let args = [getTypeDesc(p.module, seqtype),
|
let args = [getTypeDesc(p.module, seqtype),
|
||||||
genTypeInfo(p.module, seqtype, dest.lode.info), length]
|
genTypeInfo(p.module, seqtype, dest.lode.info), length]
|
||||||
|
|
@ -1187,17 +1187,23 @@ proc genNewSeqAux(p: BProc, dest: TLoc, length: Rope) =
|
||||||
linefmt(p, cpsStmts, "if ($1) { #nimGCunrefRC1($1); $1 = NIM_NIL; }$n", dest.rdLoc)
|
linefmt(p, cpsStmts, "if ($1) { #nimGCunrefRC1($1); $1 = NIM_NIL; }$n", dest.rdLoc)
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "if ($1) { #nimGCunrefNoCycle($1); $1 = NIM_NIL; }$n", dest.rdLoc)
|
linefmt(p, cpsStmts, "if ($1) { #nimGCunrefNoCycle($1); $1 = NIM_NIL; }$n", dest.rdLoc)
|
||||||
call.r = ropecg(p.module, "($1) #newSeqRC1($2, $3)", args)
|
if not lenIsZero:
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", dest.rdLoc, call.rdLoc)
|
call.r = ropecg(p.module, "($1) #newSeqRC1($2, $3)", args)
|
||||||
|
linefmt(p, cpsStmts, "$1 = $2;$n", dest.rdLoc, call.rdLoc)
|
||||||
else:
|
else:
|
||||||
call.r = ropecg(p.module, "($1) #newSeq($2, $3)", args)
|
if lenIsZero:
|
||||||
|
call.r = rope"NIM_NIL"
|
||||||
|
else:
|
||||||
|
call.r = ropecg(p.module, "($1) #newSeq($2, $3)", args)
|
||||||
genAssignment(p, dest, call, {})
|
genAssignment(p, dest, call, {})
|
||||||
|
|
||||||
proc genNewSeq(p: BProc, e: PNode) =
|
proc genNewSeq(p: BProc, e: PNode) =
|
||||||
var a, b: TLoc
|
var a, b: TLoc
|
||||||
initLocExpr(p, e.sons[1], a)
|
initLocExpr(p, e.sons[1], a)
|
||||||
initLocExpr(p, e.sons[2], b)
|
initLocExpr(p, e.sons[2], b)
|
||||||
genNewSeqAux(p, a, b.rdLoc)
|
let lenIsZero = optNilSeqs notin p.options and
|
||||||
|
e[2].kind == nkIntLit and e[2].intVal == 0
|
||||||
|
genNewSeqAux(p, a, b.rdLoc, lenIsZero)
|
||||||
gcUsage(p.config, e)
|
gcUsage(p.config, e)
|
||||||
|
|
||||||
proc genNewSeqOfCap(p: BProc; e: PNode; d: var TLoc) =
|
proc genNewSeqOfCap(p: BProc; e: PNode; d: var TLoc) =
|
||||||
|
|
@ -1297,7 +1303,8 @@ proc genSeqConstr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
elif d.k == locNone:
|
elif d.k == locNone:
|
||||||
getTemp(p, n.typ, d)
|
getTemp(p, n.typ, d)
|
||||||
# generate call to newSeq before adding the elements per hand:
|
# generate call to newSeq before adding the elements per hand:
|
||||||
genNewSeqAux(p, dest[], intLiteral(sonsLen(n)))
|
genNewSeqAux(p, dest[], intLiteral(sonsLen(n)),
|
||||||
|
optNilSeqs notin p.options and n.len == 0)
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
initLoc(arr, locExpr, n[i], OnHeap)
|
initLoc(arr, locExpr, n[i], OnHeap)
|
||||||
arr.r = ropecg(p.module, "$1$3[$2]", rdLoc(dest[]), intLiteral(i), dataField(p))
|
arr.r = ropecg(p.module, "$1$3[$2]", rdLoc(dest[]), intLiteral(i), dataField(p))
|
||||||
|
|
@ -1320,7 +1327,7 @@ proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) =
|
||||||
getTemp(p, n.typ, d)
|
getTemp(p, n.typ, d)
|
||||||
# generate call to newSeq before adding the elements per hand:
|
# generate call to newSeq before adding the elements per hand:
|
||||||
let L = int(lengthOrd(p.config, n.sons[1].typ))
|
let L = int(lengthOrd(p.config, n.sons[1].typ))
|
||||||
genNewSeqAux(p, d, intLiteral(L))
|
genNewSeqAux(p, d, intLiteral(L), optNilSeqs notin p.options and L == 0)
|
||||||
initLocExpr(p, n.sons[1], a)
|
initLocExpr(p, n.sons[1], a)
|
||||||
# bug #5007; do not produce excessive C source code:
|
# bug #5007; do not produce excessive C source code:
|
||||||
if L < 10:
|
if L < 10:
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ proc genTraverseProcSeq(c: TTraversalClosure, accessor: Rope, typ: PType) =
|
||||||
var i: TLoc
|
var i: TLoc
|
||||||
getTemp(p, getSysType(c.p.module.g.graph, unknownLineInfo(), tyInt), i)
|
getTemp(p, getSysType(c.p.module.g.graph, unknownLineInfo(), tyInt), i)
|
||||||
let oldCode = p.s(cpsStmts)
|
let oldCode = p.s(cpsStmts)
|
||||||
lineF(p, cpsStmts, "for ($1 = 0; $1 < $2->$3; $1++) {$n",
|
lineF(p, cpsStmts, "for ($1 = 0; $1 < ($2 ? $2->$3 : 0); $1++) {$n",
|
||||||
[i.r, accessor, lenField(c.p)])
|
[i.r, accessor, lenField(c.p)])
|
||||||
let oldLen = p.s(cpsStmts).len
|
let oldLen = p.s(cpsStmts).len
|
||||||
genTraverseProc(c, "$1$3[$2]" % [accessor, i.r, dataField(c.p)], typ.sons[0])
|
genTraverseProc(c, "$1$3[$2]" % [accessor, i.r, dataField(c.p)], typ.sons[0])
|
||||||
|
|
|
||||||
|
|
@ -377,7 +377,6 @@ proc findAll*(n: XmlNode, tag: string, result: var seq[XmlNode]) =
|
||||||
## findAll(html, "img", tags)
|
## findAll(html, "img", tags)
|
||||||
## for imgTag in tags:
|
## for imgTag in tags:
|
||||||
## process(imgTag)
|
## process(imgTag)
|
||||||
assert isNil(result) == false
|
|
||||||
assert n.k == xnElement
|
assert n.k == xnElement
|
||||||
for child in n.items():
|
for child in n.items():
|
||||||
if child.k != xnElement:
|
if child.k != xnElement:
|
||||||
|
|
|
||||||
|
|
@ -2530,10 +2530,7 @@ proc `$`*[T](x: seq[T]): string =
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
## $(@[23, 45]) == "@[23, 45]"
|
## $(@[23, 45]) == "@[23, 45]"
|
||||||
if x.isNil:
|
collectionToString(x, "@[", ", ", "]")
|
||||||
"nil"
|
|
||||||
else:
|
|
||||||
collectionToString(x, "@[", ", ", "]")
|
|
||||||
|
|
||||||
# ----------------- GC interface ---------------------------------------------
|
# ----------------- GC interface ---------------------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
discard """
|
discard """
|
||||||
output: '''obj2 nil
|
output: '''obj2 @[]
|
||||||
obj nil
|
obj @[]
|
||||||
obj3 nil
|
obj3 @[]
|
||||||
3
|
3
|
||||||
obj2 nil
|
obj2 @[]
|
||||||
obj nil
|
obj @[]
|
||||||
obj3 nil'''
|
obj3 @[]'''
|
||||||
cmd: "nim c -r --threads:on $file"
|
cmd: "nim c -r --threads:on $file"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ doAssert "nan" == $(0.0/0.0)
|
||||||
# nil tests
|
# nil tests
|
||||||
# maybe a bit inconsistent in types
|
# maybe a bit inconsistent in types
|
||||||
var x: seq[string]
|
var x: seq[string]
|
||||||
doAssert "nil" == $(x)
|
doAssert "@[]" == $(x)
|
||||||
|
|
||||||
var y: string
|
var y: string
|
||||||
doAssert "" == $(y)
|
doAssert "" == $(y)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue