-
Notifications
You must be signed in to change notification settings - Fork 1
Performance
The primary purpose of SkeinforgeEngine is educational, but an interesting secondary goal is to analyse the performance to see if it can be improved. The performance metric is quite straightforward: how long does it take to skein a particular file.
This page makes a comparison between Skeinforge, SFACT and SkeinforgeEngine. The latter using several variation.
It should be pointed out that the results here only give an indication of the performance. In my testing I saw the same test produce wildly different times across runs. For this reason I performed each test thrice and averaged the results. I also ran an initial test, without recording the result, to allow python to produce pyc files etc.
Also, by the time of writing this, the results are out of date. Each of the programs are under a rapid development cycle and so the versions should be taken into account, and all results are purely indicators as to the general improvements that may be possible.
It's also worth mentioning that much of the functionality has been removed during the refactoring of SkeinforgeEngine, for example the flexible plugin system, the GUI, etc. However the core function of skeining a 3d Model remains and so a comparison remains useful.
Three programs:
- Skeinforge v45 (11.11.08)
- SFACT v42.4.1 (11.09.15)
- SkeinforgeEngine (latest, 11.11.07) (refactored from SFACT v42.4.1)
SkeinforgeEngine Variations
- Multiprocessing of Inset plugin - utilising python's multiprocessing module to process several layers in parallel. This has only implemented for the inset plugin.
- PyPy interpreter - Using the PyPy implementation of python.
- PyPy interpreter with inset multiprocessing - A combination of the above two variations.
Six files were used, ranging in size and complexity. The smallest being the test file that ships with Skeinforge (test.stl), the largest, and most complex, being a plate of mendel parts (mendelplate.stl).
A breakdown of various metadata is given in the following chart. The attributes being:
- Size in bytes
- Number of vertices in the STL file
- Number of commands in the resulting gcode file (indicator only)
- Number of layers
- Number of nested rings (unique perimeters)
The majority of the SkeinforgeEngine refactoring did not involve many changes to the core algorithms used to calculate the gcode paths. Therefore it is not surprising to find the majority of the time still spent on the carving and fill algorithms. The larger test files yield similar times for these plugins, whilst smaller files fair better. This can be explained by function inlining, simplificiation of plugin structure and moving data processing from files to memory, i.e. not parsing the intermediate gcode file for each plugin. Generally smaller files yielded a 40-50% speedup, whereas the larger files gained a few seconds on SFACT but performed worse than the latest skeinforge.
Parallelising the inset plugin produced worse results for the smallest file, presumably due to the overhead of managing the processors. However benefits started to appear with larger files, and became progressively better as the size of the file increased. Yielding a ~30% improvement for the largest files. The effort in parallelising the other plugins is worth further investigation.
The biggest improvements came from switching python implementations to PyPy. Again, the smallest file produced worse results, presumably from various overheads, but the other files yieled excellent gains - up to 150% speedup versus SFACT in some cases.
Interestingly the multiprocessing functionality of the inset module seemed to adversely affect the PyPy interpreter and the combination of the two producing noticably worse results, but still markedly better for large files.
View large version | View as bar chart
The impact of PyPy really shows with the largest file, the mendel plate, and this is shown in it's own graph below.
(Note: the SkeinforgeEngine multiprocessing run is not included as the memory used by the application went through the roof and hung my machine. This is no doubt due to sloppy memory usage introduced by my refactoring and requires further investigation.)
Link to results Excel spreadsheet
Python's interoperability opens several avenues for refactoring. It would be possible to rewrite the slower alogrithms (fill, inset) in C, or utilise Cython to compile python-like code to C. This approach requires deep seated refactoring of the application (e.g. the core utility classes) in order to yield results. The benefits could well be worthwhile.