By Jewe | January 18, 2016
About upcoming changes in the next version of JewelScript.
A while back, I have begun working on an update for the JewelScript library. This time though, I decided that the target for improvements should be the runtime environment, not the scripting language and compiler.
In the past year, I have identified a few key areas in the virtual machine and runtime environment, that needed improvement. One “bottleneck”, for example, was the design of the memory management prior to Version 1.4. Although it worked and performed well with smaller scripts, it didn’t scale very well, if tasks became increasingly complex.
The memory management in JewelScript is based on an algorithm for fast allocation and deallocation of small objects. It’s purpose is to avoid memory fragmentation and boost performance by caching and re-using already allocated blocks – rather than immediately returning them to the system. This lead two two major issues:
1.) Once a script has allocated a certain amount of memory, this memory will remain cached for the entire life-cycle of the VM; it will not be returned to the system, although the script may not use it anymore. Imagine a script that uses 1 GB of RAM during initialization, but after that only needs a few MB to keep running. In such a scenario, the old memory management kept 1 GB of RAM cached, in effect spoiling it.
2.) Because the algorithm used for allocating blocks was an ON algorithm, the memory manager became progressively slower the more blocks were in use. As an extreme example, if you allocated a two dimensional array of 2000 by 2000 elements in JewelScript 1.3, this literally took minutes to complete!
In the current 1.4 VM overhaul branch, I address these issues with an improved version of the memory management. First of all, the garbage collector has been extended to check for unused memory buckets. When run, GC will now free unused, cached memory, returning precious resources back to the system.
In addition, the new implementation is no longer an ON algorithm. While it is slightly slower than the old version for smaller scripts, it’s performance will remain almost constant, as memory utilization of the script grows. In the current beta build of 1.4, allocating a 2000 by 2000 array is almost as fast as allocating a 100 by 100 array.
Another issue in JewelScript prior to 1.4 was the dynamic array class used by the compiler. When adding new elements to this array, it would reallocate itself to make room, causing too many memory allocations and block copy operations in the long run.
I have replaced this by a smarter “Fragmented Array” implementation. For random access, the fragmented array is slightly slower than the old implementation. However, it does not rely on reallocation, and thus doesn’t need to copy large memory blocks. This should reduce compile times, especially on slower computers.
Comments are closed.