Hello, there's freearray() at end of setarrvalue(). It can be replaced with free() if ownership of all strings will be given away: for (r = val; *r;) *p++ = ztrdup(*r++); becomes: for (r = val; *r;) *p++ = *r++; and freearray(val) -> free(val). It is very provable that this is correct: `val` must have data of the same kind as ztrdup() produces, as it is simply passed to freearray(), where zsfree() is called on each string. Test function: test_fun() { local -a arr arr=( "a" ) repeat 20; do arr+=( $arr ) done } Runs 2189 ms when no optimization, 1653 ms when optimized (when ran 3 times, test script attached). This is a mild optimization as most often short arrays are being assigned, not long like in the test function, but still, this can save one's day in certain situations. -- Sebastian Gniazdowski psprint@xxxxxxxxxxxx
diff --git a/Src/params.c b/Src/params.c index 330f22b..5a3e0d3 100644 --- a/Src/params.c +++ b/Src/params.c @@ -2648,14 +2648,18 @@ setarrvalue(Value v, char **val) for (i = 0; i < v->start; i++) *p++ = i < pre_assignment_length ? ztrdup(*q++) : ztrdup(""); for (r = val; *r;) - *p++ = ztrdup(*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); - freearray(val); + + /* Ownership of all strings has been + * given away, can plainly free */ + free(val); } }
Attachment:
test1.zsh
Description: Binary data