Superstrings, like "a{b}c", are managed in the AST as a special group of sub-expression nodes that are either literal string parts or standard expressions.
The previous example is basically `["a", b, "c"]`
Previously, the compilation of super-strings was direct: the values are grouped in an array and `to_s` is called on it.
So in fact `"a{b}c"` was compiled as `["a", b, "c"].to_s`.
This basic implementation is simple and correct. But it has some drawbacks:
* a new Array[Object] (and a NativeArray[Object]) is allocated each time the super-string is evaluated.
* all elements are to_s-ized in `Array::to_s`, even the literal parts.
* an additional NativeArray[String] is allocated in `Array:to_s` to do the fast concatenation.
Because of the numerous allocations, superstrings caused a lot of work to the GC.
This PR provides a better, but more complex implementation:
* instead of an Array[Object], a NativeArray[String] is directly build and a fast concatenation `native_to_s` is invoked.
* the allocated NativeArray is cached in a static variable so it can be reused in next evaluation.
* the literal string parts are stored in the native array as is, and only once just after the allocation of the native array.
Results for nitc/nitc/nitc:
before: 0m6.076s
after: 0m5.512s (-9% not bad!)
Pull-Request: #1219
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>