summaryrefslogtreecommitdiff
path: root/op.c
diff options
context:
space:
mode:
authorGisle Aas <gisle@aas.no>1998-06-24 22:26:48 +0200
committerGurusamy Sarathy <gsar@cpan.org>1998-06-28 19:44:19 +0000
commit89ea29081d863efc8d483f9cbe1c4e1dbb831359 (patch)
treec7e55c90b8da9656b7bb2b9467f183842bed6aae /op.c
parent95a449b8d7e85665d931cb07abe3a369141c3170 (diff)
downloadperl-89ea29081d863efc8d483f9cbe1c4e1dbb831359.tar.gz
Optimize foreach (1..1000000)
Message-ID: <m3lnqmwt93.fsf@furu.g.aas.no> p4raw-id: //depot/perl@1239
Diffstat (limited to 'op.c')
-rw-r--r--op.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/op.c b/op.c
index d39020504c..530c29dd1c 100644
--- a/op.c
+++ b/op.c
@@ -3024,12 +3024,44 @@ newFOROP(I32 flags,char *label,line_t forline,OP *sv,OP *expr,OP *block,OP *cont
#endif
}
if (expr->op_type == OP_RV2AV || expr->op_type == OP_PADAV) {
- expr = scalar(ref(expr, OP_ITER));
+ expr = mod(force_list(scalar(ref(expr, OP_ITER))), OP_GREPSTART);
iterflags |= OPf_STACKED;
}
+ else if (expr->op_type == OP_NULL &&
+ (expr->op_flags & OPf_KIDS) &&
+ ((BINOP*)expr)->op_first->op_type == OP_FLOP)
+ {
+ /* Basically turn for($x..$y) into the same as for($x,$y), but we
+ * set the STACKED flag to indicate that these values are to be
+ * treated as min/max values by 'pp_iterinit'.
+ */
+ UNOP* flip = (UNOP*)((UNOP*)((BINOP*)expr)->op_first)->op_first;
+ CONDOP* range = (CONDOP*) flip->op_first;
+ OP* left = range->op_first;
+ OP* right = left->op_sibling;
+ LISTOP* list;
+
+ range->op_flags &= ~OPf_KIDS;
+ range->op_first = Nullop;
+
+ list = (LISTOP*)newLISTOP(OP_LIST, 0, left, right);
+ list->op_first->op_next = range->op_true;
+ left->op_next = range->op_false;
+ right->op_next = (OP*)list;
+ list->op_next = list->op_first;
+
+ op_free(expr);
+ expr = (OP*)(list);
+ null(expr);
+ iterflags |= OPf_STACKED;
+ }
+ else {
+ expr = mod(force_list(expr), OP_GREPSTART);
+ }
+
+
loop = (LOOP*)list(convert(OP_ENTERITER, iterflags,
- append_elem(OP_LIST, mod(force_list(expr), OP_GREPSTART),
- scalar(sv))));
+ append_elem(OP_LIST, expr, scalar(sv))));
assert(!loop->op_next);
Renew(loop, 1, LOOP);
loop->op_targ = padoff;