Merge: Fast super strings
authorJean Privat <jean@pryen.org>
Sat, 28 Mar 2015 01:34:45 +0000 (08:34 +0700)
committerJean Privat <jean@pryen.org>
Sat, 28 Mar 2015 01:34:45 +0000 (08:34 +0700)
commit87235c87c9a3ec0feab4118fbbb0e8949fae7b87
tree7683b7d08c051516e2aebad293cd71036170bd5b
parent4860c1e2ba88b281a1ea8de89968598da467d93d
parent524a51ab8662605c4a120406c81d2b8491f8901d
Merge: Fast super strings

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>
src/compiler/separate_compiler.nit