Skip to content
Browse files

Remove some redundant allocations from list iteration

  • Loading branch information...
1 parent 176cbba commit 202659e04ad20f057b558315f81c051777ebbbf4 @sorear committed May 28, 2011
Showing with 78 additions and 17 deletions.
  1. +11 −4 lib/Builtins.cs
  2. +3 −3 lib/Cursor.cs
  3. +4 −6 lib/JSYNC.cs
  4. +1 −1 lib/Kernel.cs
  5. +1 −1 lib/ObjModel.cs
  6. +10 −2 lib/Utils.cs
  7. +48 −0 src/niecza
View
15 lib/Builtins.cs
@@ -944,7 +944,7 @@ class SubstrLValue: Variable {
public static string[] UnboxLoS(Variable args) {
List<string> la = new List<string>();
- VarDeque iter = new VarDeque(args);
+ VarDeque iter = start_iter(args);
while (Kernel.IterHasFlat(iter, true)) {
Variable v = iter.Shift();
la.Add(v.Fetch().mo.mro_raw_Str.Get(v));
@@ -1010,8 +1010,15 @@ class SubstrLValue: Variable {
return Kernel.NewROScalar(l);
}
+ public static VarDeque start_iter(Variable thing) {
+ if (thing.islist)
+ return thing.Fetch().mo.mro_raw_iterator.Get(thing);
+ else
+ return new VarDeque(thing);
+ }
+
public static Variable bif_array_constructor(Variable bits) {
- VarDeque rest = new VarDeque(bits);
+ VarDeque rest = start_iter(bits);
VarDeque items = new VarDeque();
while (Kernel.IterHasFlat(rest, true))
items.Push(Kernel.NewRWScalar(Kernel.AnyMO, rest.Shift().Fetch()));
@@ -1101,7 +1108,7 @@ class ZipSource : ItemSource {
public ZipSource(Variable[] pcl) {
sources = new VarDeque[pcl.Length];
for (int i = 0; i < pcl.Length; i++)
- sources[i] = new VarDeque(pcl[i]);
+ sources[i] = start_iter(pcl[i]);
}
public override bool TryGet(out Variable[] r, bool block) {
@@ -1132,7 +1139,7 @@ class CrossSource: ItemSource {
basic_top = new Variable[pcl.Length];
iter_top = new Variable[pcl.Length];
for (int i = 0; i < pcl.Length; i++) {
- iter[i] = new VarDeque(pcl[i]);
+ iter[i] = start_iter(pcl[i]);
}
}
View
6 lib/Cursor.cs
@@ -226,7 +226,7 @@ public sealed class RxFrame {
}
public void InitCursorList(Variable obj) {
- st.subrule_iter = new VarDeque(obj);
+ st.subrule_iter = Builtins.start_iter(obj);
}
public Variable GetCursorList() {
@@ -564,7 +564,7 @@ public Cursor(P6any proto, string text, P6any actions)
public static Cursor Synthetic(Cursor parent, string method, int from,
int to, Variable caplist) {
- VarDeque iter = new VarDeque(caplist);
+ VarDeque iter = Builtins.start_iter(caplist);
CapInfo ci = null;
while (Kernel.IterHasFlat(iter, true)) {
P6any pair = iter.Shift().Fetch();
@@ -1694,7 +1694,7 @@ public class Lexer {
return (((P6any[])th.lex1)[th.lexi0++]).Invoke(th,
new Variable[] { Kernel.NewROScalar(th.rx.MakeCursor()) }, null);
case 3:
- th.lex2 = new VarDeque((Variable) th.resultSlot);
+ th.lex2 = Builtins.start_iter((Variable) th.resultSlot);
goto case 4;
case 4:
if (!Kernel.IterHasFlat((VarDeque)th.lex2, true))
View
10 lib/JSYNC.cs
@@ -49,15 +49,13 @@ public class JsyncWriter {
void WriteArray(P6any obj) {
int a = nextanchor++;
anchors[obj] = a;
- Kernel.RunInferior(obj.InvokeMethod(Kernel.GetInferiorRoot(), "eager",
- new Variable[] { Kernel.NewROScalar(obj) }, null));
+ VarDeque iter = obj.mo.mro_raw_iterator.Get(Kernel.NewROScalar(obj));
o.AppendFormat("[\"&A{0}\"", a);
contUsed = true;
- VarDeque vd = (VarDeque) obj.GetSlot("items");
- for (int i = 0; i < vd.Count(); i++) {
+ while (Kernel.IterHasFlat(iter, true)) {
o.Append(',');
- WriteObj(vd[i].Fetch());
+ WriteObj(iter.Shift().Fetch());
}
o.Append(']');
}
@@ -841,7 +839,7 @@ public class JsonWriter {
}
o.Append('}');
} else if (def && obj.Isa(Kernel.ListMO)) {
- VarDeque iter = new VarDeque(Kernel.NewRWListVar(obj));
+ VarDeque iter = obj.mo.mro_raw_iterator.Get(Kernel.NewROScalar(obj));
o.Append('[');
while (Kernel.IterHasFlat(iter, true)) {
if (comma) o.Append(',');
View
2 lib/Kernel.cs
@@ -2449,7 +2449,7 @@ public class MMDCandidateLongname {
public static Frame PromoteToList(Frame th, Variable v) {
if (!v.islist) {
P6opaque lst = new P6opaque(Kernel.ListMO);
- lst.slots[0 /*items*/] = new VarDeque(new Variable[] { v });
+ lst.slots[0 /*items*/] = new VarDeque(v);
lst.slots[1 /*rest*/ ] = new VarDeque();
th.resultSlot = Kernel.NewRWListVar(lst);
return th;
View
2 lib/ObjModel.cs
@@ -84,7 +84,7 @@ public abstract class IndexHandler {
}
protected Variable Slice(Variable obj, Variable key) {
- VarDeque iter = new VarDeque(key);
+ VarDeque iter = Builtins.start_iter(key);
List<Variable> items = new List<Variable>();
while (Kernel.IterHasFlat(iter, true))
items.Add(Get(obj, iter.Shift()));
View
12 lib/Utils.cs
@@ -84,8 +84,16 @@ public sealed class VarDeque {
Push(vrs[i]);
}
- public void PushD(VarDeque vrs) { PushN(vrs.CopyAsArray()); }
- public void UnshiftD(VarDeque vrs) { UnshiftN(vrs.CopyAsArray()); }
+ public void PushD(VarDeque vrs) {
+ if (vrs == this) { PushN(vrs.CopyAsArray()); return; }
+ for (int i = 0; i < vrs.count; i++)
+ Push(vrs[i]);
+ }
+ public void UnshiftD(VarDeque vrs) {
+ if (vrs == this) { UnshiftN(vrs.CopyAsArray()); return; }
+ for (int i = vrs.count - 1; i >= 0; i--)
+ Unshift(vrs[i]);
+ }
public Variable Shift() {
int index = head++;
View
48 src/niecza
@@ -145,6 +145,54 @@ method parameter($/) {
}
augment class CgOp {
+method start_iter($i) { self._cgop("start_iter", $i) }
+}
+
+augment class Op::ImmedForLoop { #OK
+ method code_labelled($body, $l) {
+ my $id = ::GLOBAL::NieczaActions.genid;
+
+ CgOp.rnull(CgOp.letn(
+ "!iter$id", CgOp.start_iter($.source.cgop($body)),
+ (map { $_, CgOp.null('var') }, @$.var),
+ CgOp.whileloop(0, 0,
+ CgOp.iter_hasflat(CgOp.letvar("!iter$id")),
+ CgOp.prog(
+ (map { CgOp.letvar($_,
+ CgOp.vvarlist_shift(CgOp.letvar("!iter$id")))},@$.var),
+ CgOp.sink(CgOp.xspan("redo$id", "next$id", 0,
+ $.sink.cgop($body),
+ 1, $l, "next$id",
+ 2, $l, "last$id",
+ 3, $l, "redo$id")))),
+ CgOp.label("last$id")));
+ }
+}
+
+augment class RxOp::ProtoRedis { #OK
+ method code($) {
+ CgOp.letn(
+ "fns", CgOp.run_dispatch(CgOp.callframe,
+ CgOp.fetch(CgOp.scopedlex('self'))),
+ "i", CgOp.int(0),
+ "ks", CgOp.null('vvarlist'),
+ CgOp.pushcut('LTM'),
+ CgOp.label('nextfn'),
+ CgOp.cgoto('backtrack',
+ CgOp.compare('>=', CgOp.letvar("i"),
+ CgOp.mrl_count(CgOp.letvar("fns")))),
+ CgOp.rxpushb('LTM', 'nextfn'),
+ CgOp.letvar("ks", CgOp.start_iter(
+ CgOp.subcall(CgOp.mrl_index(CgOp.letvar("i"),
+ CgOp.letvar("fns")), CgOp.rxcall('MakeCursorV')))),
+ CgOp.letvar("i", CgOp.arith('+', CgOp.letvar("i"), CgOp.int(1))),
+ CgOp.label('nextcsr'),
+ CgOp.ncgoto('backtrack', CgOp.iter_hasflat(CgOp.letvar('ks'))),
+ CgOp.rxpushb('SUBRULE', 'nextcsr'),
+ CgOp.rxcall('EndWith', CgOp.cast('cursor',
+ CgOp.fetch(CgOp.vvarlist_shift(CgOp.letvar('ks'))))),
+ CgOp.goto('backtrack'));
+ }
}
my $usage = q:to/EOM/;

0 comments on commit 202659e

Please sign in to comment.
Something went wrong with that request. Please try again.