Hello, first thing – the dupstring_glen() that was in the code isn't needed – the value allocated was only read, not written to in any place in the code: - z = dupstring_glen(v->pm->gsu.s->getfn(v->pm), (unsigned*) &zlen); + z = v->pm->gsu.s->getfn(v->pm); + zlen = strlen(z); This gives significant speed up – although only for very large buffers – attached testopt4bb.zsh: i=$(( 20000 )) while (( i -- )); do a+="aaaaaaaaaaaaaaaaaaaaaaaaa" done runs for 953 ms with optimizations, 1576 ms without them. Second: the same that I did with setarrvalue – if we assign a[10]="a", and 10-th element already exists, i.e. size of string doesn't change, then instead of: x = (char *) zalloc(newsize + 1); strncpy(x, z, v->start); strcpy(x + v->start, val); strcat(x + v->start, z + v->end); v->pm->gsu.s->setfn(v->pm, x); It is done: /* Size doesn't change, can limit actions to only * overwriting bytes in already allocated string */ strncpy(z + v->start, val, vlen); Condition excludes special parameters: /* Does new size differ? */ if ( newsize != zlen || v->pm->node.flags & PM_SPECIAL ) { Test code: a="exampletext" repeat 12 a+="$a" strtest() { repeat 60000; do a[10]="a" done } runs 366 ms vs 876 ms. The string has length 45056 elements, and there are as much as 60k repetitions, so previous code was actually already fast despite the extra zalloc, strncpy, strcat – which is little weird. That said, the optimization can save one's day in certain situations. Also added extensive tests of string assignments. PS. The code again removes "+ 1" from new size computation. The comment explains why: /* Characters preceding start index + characters of what is assigned + characters following end index */ newsize = v->start + vlen + (zlen - v->end); -- Sebastian Gniazdowski psprint@fastmail.com