Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: [PATCH] zrealloc on array+=( )
- X-seq: zsh-workers 40718
- From: Sebastian Gniazdowski <psprint3@xxxxxxxxxxxx>
- To: zsh-workers@xxxxxxx
- Subject: Re: [PATCH] zrealloc on array+=( )
- Date: Sat, 04 Mar 2017 05:47:39 -0800
- Dkim-signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=fastmail.com; h= content-transfer-encoding:content-type:date:from:message-id :mime-version:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= mesmtp; bh=goJ1zQXvI0chBLHfbA6yta/niho=; b=cU2amkrSLImrCmK8ieLQz JcejLongJkmxi+NzRvNHBHCZp5E+c7uvZPFFIO2TD0Hpd2gnK8E094UoncQcgQSC 7Eb1P4Br45J9hTGrD1iWy0/twOdhv4Yba6knsFjYYHk4b539aA8z2oBU5osubiX4 01fNZHXt6KNnHGSC1gLsyE=
- Dkim-signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:message-id:mime-version:subject:to:x-me-sender :x-me-sender:x-sasl-enc; s=smtpout; bh=goJ1zQXvI0chBLHfbA6yta/ni ho=; b=elFxCkJyNpOuW1E67UM4fpVvXL+jLY8Moyez9TMR2Lpftv8C9hq2y+8KF MfgouKoPl6FA4Pg9bOwRrfklGj3w6a4BKR2rKd8JZqTV1TaFMpb2umWE4AH7x4aK E/D6HnmisnriwZOH8EfwU7f+DOUs46kKeBXqUa7VJoKbOeu/y8=
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
Hello,
I revisited the patch, tested with debug prints, added test cases that
stress things out. No code changes.
Thought to test how Bash (3.2) performs on appends:
# fun() { local -a arr; i=5001; while (( -- i )); do arr+=( "The
appended test string of medium length" ); done; }
# time fun
real 0m0.221s
user 0m0.214s
sys 0m0.004s
So it's 200 ms. The same test with no-zrealloc-Zsh is 2.94 s. With the
patch it's 116 ms (using time tool, typeset -F SECONDS reveals it's 4
ms). So this can be a motivation to apply the patch. We can leverage the
fact that operating system has size of the array and can extend it, and
this way beat Bash. Of course, the real deal here is to be able to do
data processing, e.g. log gathering, etc.
--
Sebastian Gniazdowski
psprint3@xxxxxxxxxxxx
diff --git a/Src/params.c b/Src/params.c
index 19cbb1c..8942fef 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -2723,24 +2723,57 @@ setarrvalue(Value v, char **val)
*p++ = *r++;
}
} else {
- p = new = (char **) zalloc(sizeof(char *)
- * (post_assignment_length + 1));
-
- for (i = 0; i < v->start; i++)
- *p++ = i < pre_assignment_length ? ztrdup(*q++) : ztrdup("");
- for (r = val; *r;) {
- /* Give away ownership of the string */
- *p++ = *r++;
- }
- if (v->end < pre_assignment_length)
- for (q = old + v->end; *q;)
- *p++ = ztrdup(*q++);
- *p = NULL;
+ /* arr+=( ... )
+ * arr[${#arr}+x,...]=( ... ) */
+ if (post_assignment_length > pre_assignment_length &&
+ pre_assignment_length <= v->start &&
+ pre_assignment_length > 0 &&
+ v->pm->gsu.a->setfn == arrsetfn)
+ {
+ p = new = (char **) zrealloc(old, sizeof(char *)
+ * (post_assignment_length + 1));
+
+ p += pre_assignment_length; /* after old elements */
+
+ /* Consider 1 < 0, case for a=( 1 ); a[1,..] =
+ * 1 < 1, case for a=( 1 ); a[2,..] = */
+ if (pre_assignment_length < v->start) {
+ for (i = pre_assignment_length; i < v->start; i++) {
+ *p++ = ztrdup("");
+ }
+ }
+
+ for (r = val; *r;) {
+ /* Give away ownership of the string */
+ *p++ = *r++;
+ }
+
+ /* v->end doesn't matter:
+ * a=( 1 2 ); a[4,100]=( a b ); echo "${(q@)a}"
+ * 1 2 '' a b */
+ *p = NULL;
+
+ v->pm->u.arr = NULL;
+ v->pm->gsu.a->setfn(v->pm, new);
+ } else {
+ p = new = (char **) zalloc(sizeof(char *)
+ * (post_assignment_length + 1));
+ for (i = 0; i < v->start; i++)
+ *p++ = i < pre_assignment_length ? ztrdup(*q++) : ztrdup("");
+ for (r = val; *r;) {
+ /* Give away ownership of the string */
+ *p++ = *r++;
+ }
+ if (v->end < pre_assignment_length)
+ for (q = old + v->end; *q;)
+ *p++ = ztrdup(*q++);
+ *p = NULL;
+
+ v->pm->gsu.a->setfn(v->pm, new);
+ }
DPUTS2(p - new != post_assignment_length, "setarrvalue: wrong allocation: %d 1= %lu",
post_assignment_length, (unsigned long)(p - new));
-
- v->pm->gsu.a->setfn(v->pm, new);
}
/* Ownership of all strings has been
diff --git a/Test/A06assign.ztst b/Test/A06assign.ztst
index bf39aee..fd2b417 100644
--- a/Test/A06assign.ztst
+++ b/Test/A06assign.ztst
@@ -133,6 +133,72 @@
>1 2 42 43 44 5
>1 2 42 100 99 5
+# (subsection: append to array)
+
+ array=( )
+ array[5,6]=( 1 2 3 )
+ print $array
+ print "${(q@)array}"
+0:Append to empty array by range
+>1 2 3
+>'' '' '' '' 1 2 3
+
+ array=( a )
+ array[5,6]=( 1 2 3 )
+ print $array
+ print "${(q@)array}"
+0:Append to 1-element array by range
+>a 1 2 3
+>a '' '' '' 1 2 3
+
+ array=( a b )
+ array[5,6]=( 1 2 3 )
+ print $array
+ print "${(q@)array}"
+0:Append to 2-element array by range
+>a b 1 2 3
+>a b '' '' 1 2 3
+
+ array=( a b )
+ array[5,5]=( 1 2 3 )
+ print $array
+ print "${(q@)array}"
+0:Append to 2-element array by [a,a] range
+>a b 1 2 3
+>a b '' '' 1 2 3
+
+ array=( a b c d )
+ array[5,6]=( 1 2 3 )
+ print $array
+ print "${(q@)array}"
+0:Append array by range, continuously
+>a b c d 1 2 3
+>a b c d 1 2 3
+
+ array=( a b c d )
+ array[5,5]=( 1 2 3 )
+ print $array
+ print "${(q@)array}"
+0:Append array by [a,a] range, continuously
+>a b c d 1 2 3
+>a b c d 1 2 3
+
+ array=( )
+ array+=( 1 2 3 )
+ print $array
+ print "${(q@)array}"
+0:Append empty array via +=
+>1 2 3
+>1 2 3
+
+ array=( a )
+ array+=( 1 2 3 )
+ print $array
+ print "${(q@)array}"
+0:Append 1-element array via +=
+>a 1 2 3
+>a 1 2 3
+
# tests of var+=scalar
s+=foo
Messages sorted by:
Reverse Date,
Date,
Thread,
Author