added system.newSeqOfCap for improved efficiency

This commit is contained in:
Andreas Rumpf 2016-07-15 17:04:14 +02:00
commit b7c1be03c8
7 changed files with 47 additions and 4 deletions

View file

@ -545,7 +545,7 @@ type
mEcho, mShallowCopy, mSlurp, mStaticExec, mEcho, mShallowCopy, mSlurp, mStaticExec,
mParseExprToAst, mParseStmtToAst, mExpandToAst, mQuoteAst, mParseExprToAst, mParseStmtToAst, mExpandToAst, mQuoteAst,
mUnaryLt, mInc, mDec, mOrd, mUnaryLt, mInc, mDec, mOrd,
mNew, mNewFinalize, mNewSeq, mNew, mNewFinalize, mNewSeq, mNewSeqOfCap,
mLengthOpenArray, mLengthStr, mLengthArray, mLengthSeq, mLengthOpenArray, mLengthStr, mLengthArray, mLengthSeq,
mXLenStr, mXLenSeq, mXLenStr, mXLenSeq,
mIncl, mExcl, mCard, mChr, mIncl, mExcl, mCard, mChr,

View file

@ -1141,6 +1141,16 @@ proc genNewSeq(p: BProc, e: PNode) =
genNewSeqAux(p, a, b.rdLoc) genNewSeqAux(p, a, b.rdLoc)
gcUsage(e) gcUsage(e)
proc genNewSeqOfCap(p: BProc; e: PNode; d: var TLoc) =
let seqtype = skipTypes(e.typ, abstractVarRange)
var a: TLoc
initLocExpr(p, e.sons[1], a)
putIntoDest(p, d, e.typ, ropecg(p.module,
"($1)#nimNewSeqOfCap($2, $3)", [
getTypeDesc(p.module, seqtype),
genTypeInfo(p.module, seqtype), a.rdLoc]))
gcUsage(e)
proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
var tmp: TLoc var tmp: TLoc
var t = e.typ.skipTypes(abstractInst) var t = e.typ.skipTypes(abstractInst)
@ -1712,6 +1722,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
of mNew: genNew(p, e) of mNew: genNew(p, e)
of mNewFinalize: genNewFinalize(p, e) of mNewFinalize: genNewFinalize(p, e)
of mNewSeq: genNewSeq(p, e) of mNewSeq: genNewSeq(p, e)
of mNewSeqOfCap: genNewSeqOfCap(p, e, d)
of mSizeOf: of mSizeOf:
let t = e.sons[1].typ.skipTypes({tyTypeDesc}) let t = e.sons[1].typ.skipTypes({tyTypeDesc})
putIntoDest(p, d, e.typ, "((NI)sizeof($1))" % [getTypeDesc(p.module, t)]) putIntoDest(p, d, e.typ, "((NI)sizeof($1))" % [getTypeDesc(p.module, t)])

View file

@ -1755,6 +1755,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
else: else:
binaryExpr(p, n, r, "", "isset($1[$2])") binaryExpr(p, n, r, "", "isset($1[$2])")
of mNewSeq: genNewSeq(p, n) of mNewSeq: genNewSeq(p, n)
of mNewSeqOfCap: unaryExpr(p, n, r, "", "[]" | "array()")
of mOf: genOf(p, n, r) of mOf: genOf(p, n, r)
of mReset: genReset(p, n) of mReset: genReset(p, n)
of mEcho: genEcho(p, n, r) of mEcho: genEcho(p, n, r)

View file

@ -597,16 +597,27 @@ proc genNew(c: PCtx; n: PNode) =
c.freeTemp(dest) c.freeTemp(dest)
proc genNewSeq(c: PCtx; n: PNode) = proc genNewSeq(c: PCtx; n: PNode) =
let dest = if needsAsgnPatch(n.sons[1]): c.getTemp(n.sons[1].typ) let t = n.sons[1].typ
let dest = if needsAsgnPatch(n.sons[1]): c.getTemp(t)
else: c.genx(n.sons[1]) else: c.genx(n.sons[1])
let tmp = c.genx(n.sons[2]) let tmp = c.genx(n.sons[2])
c.gABx(n, opcNewSeq, dest, c.genType(n.sons[1].typ.skipTypes( c.gABx(n, opcNewSeq, dest, c.genType(t.skipTypes(
abstractVar-{tyTypeDesc}))) abstractVar-{tyTypeDesc})))
c.gABx(n, opcNewSeq, tmp, 0) c.gABx(n, opcNewSeq, tmp, 0)
c.freeTemp(tmp) c.freeTemp(tmp)
c.genAsgnPatch(n.sons[1], dest) c.genAsgnPatch(n.sons[1], dest)
c.freeTemp(dest) c.freeTemp(dest)
proc genNewSeqOfCap(c: PCtx; n: PNode; dest: var TDest) =
let t = n.typ
let tmp = c.getTemp(n.sons[1].typ)
c.gABx(n, opcLdNull, dest, c.genType(t))
c.gABx(n, opcLdImmInt, tmp, 0)
c.gABx(n, opcNewSeq, dest, c.genType(t.skipTypes(
abstractVar-{tyTypeDesc})))
c.gABx(n, opcNewSeq, tmp, 0)
c.freeTemp(tmp)
proc genUnaryABC(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) = proc genUnaryABC(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
let tmp = c.genx(n.sons[1]) let tmp = c.genx(n.sons[1])
if dest < 0: dest = c.getTemp(n.typ) if dest < 0: dest = c.getTemp(n.typ)
@ -782,6 +793,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
of mNewSeq: of mNewSeq:
unused(n, dest) unused(n, dest)
c.genNewSeq(n) c.genNewSeq(n)
of mNewSeqOfCap: c.genNewSeqOfCap(n, dest)
of mNewString: of mNewString:
genUnaryABC(c, n, dest, opcNewStr) genUnaryABC(c, n, dest, opcNewStr)
# XXX buggy # XXX buggy

View file

@ -669,6 +669,12 @@ proc newSeq*[T](len = 0.Natural): seq[T] =
## #inputStrings[3] = "out of bounds" ## #inputStrings[3] = "out of bounds"
newSeq(result, len) newSeq(result, len)
proc newSeqOfCap*[T](cap: Natural): seq[T] {.
magic: "NewSeqOfCap", noSideEffect.} =
## creates a new sequence of type ``seq[T]`` with length 0 and capacity
## ``cap``.
discard
proc len*[TOpenArray: openArray|varargs](x: TOpenArray): int {. proc len*[TOpenArray: openArray|varargs](x: TOpenArray): int {.
magic: "LengthOpenArray", noSideEffect.} magic: "LengthOpenArray", noSideEffect.}
proc len*(x: string): int {.magic: "LengthStr", noSideEffect.} proc len*(x: string): int {.magic: "LengthStr", noSideEffect.}

View file

@ -354,6 +354,12 @@ elif defined(gogc):
cast[PGenericSeq](result).reserved = len cast[PGenericSeq](result).reserved = len
cast[PGenericSeq](result).elemSize = typ.base.size cast[PGenericSeq](result).elemSize = typ.base.size
proc nimNewSeqOfCap(typ: PNimType, cap: int): pointer {.compilerproc.} =
result = newObj(typ, cap * typ.base.size + GenericSeqSize)
cast[PGenericSeq](result).len = 0
cast[PGenericSeq](result).reserved = cap
cast[PGenericSeq](result).elemSize = typ.base.size
proc growObj(old: pointer, newsize: int): pointer = proc growObj(old: pointer, newsize: int): pointer =
# the Go GC doesn't have a realloc # the Go GC doesn't have a realloc
var var
@ -447,6 +453,7 @@ elif defined(nogc) and defined(useMalloc):
result = newObj(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize)) result = newObj(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize))
cast[PGenericSeq](result).len = len cast[PGenericSeq](result).len = len
cast[PGenericSeq](result).reserved = len cast[PGenericSeq](result).reserved = len
proc newObjNoInit(typ: PNimType, size: int): pointer = proc newObjNoInit(typ: PNimType, size: int): pointer =
result = alloc(size) result = alloc(size)
@ -506,6 +513,7 @@ elif defined(nogc):
result = newObj(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize)) result = newObj(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize))
cast[PGenericSeq](result).len = len cast[PGenericSeq](result).len = len
cast[PGenericSeq](result).reserved = len cast[PGenericSeq](result).reserved = len
proc growObj(old: pointer, newsize: int): pointer = proc growObj(old: pointer, newsize: int): pointer =
result = realloc(old, newsize) result = realloc(old, newsize)
@ -545,4 +553,10 @@ else:
else: else:
include "system/gc" include "system/gc"
when not declared(nimNewSeqOfCap):
proc nimNewSeqOfCap(typ: PNimType, cap: int): pointer {.compilerproc.} =
result = newObj(typ, addInt(mulInt(cap, typ.base.size), GenericSeqSize))
cast[PGenericSeq](result).len = 0
cast[PGenericSeq](result).reserved = cap
{.pop.} {.pop.}

View file

@ -1,7 +1,6 @@
version 1.0 battle plan version 1.0 battle plan
======================= =======================
- introduce newSeqOfCap(10)
- overloading of `()` and ``.`` needs to be in .experimental - overloading of `()` and ``.`` needs to be in .experimental
- implement ``.delegate`` for .experimental - implement ``.delegate`` for .experimental
- find a solution for the x.f[T](y) gotcha - find a solution for the x.f[T](y) gotcha