Bytecode Inspection for Performance Improvement
Löppönen, Tapio (2022)
Löppönen, Tapio
2022
Master's Programme in Computing Sciences
Informaatioteknologian ja viestinnän tiedekunta - Faculty of Information Technology and Communication Sciences
This publication is copyrighted. You may download, display and print it for Your own personal use. Commercial use is prohibited.
Hyväksymispäivämäärä
2022-05-12
Julkaisun pysyvä osoite on
https://urn.fi/URN:NBN:fi:tuni-202204263674
https://urn.fi/URN:NBN:fi:tuni-202204263674
Tiivistelmä
The .NET virtual machine provides support for running cross-platform applications. The virtual machine provides cross-platform support by translating platform-independent bytecode into platform-dependent instruction during execution. The bytecode, in our case, the Common Intermediate Language, is generated by compiling C# code into the bytecode. By compiling a high-level language into bytecode, the application can be developed using a high-level language, compiled once, and deployed on multiple platforms. The .NET virtual machine uses stack architecture, which requires the C# to be converted into a stack-based bytecode during compilation. In addition to producing stack-based bytecode, the compiler removes syntactic sugar from the code. Syntactic sugar is removed by replacing complex semantics with simpler ones.
In this thesis, we performed benchmarks to determine the performance effects of high-level changes. In addition to benchmarks, we inspected the changes on the bytecode level. The benchmark methods iterate over a sequence of elements, counting the sum of all elements. We started by comparing the performance differences between arrays and lists. The list showed a small overhead in most cases and a noticeable overhead in some cases. Because the generic list contains different implementation details, we performed additional benchmarks on the used syntactic sugar. The additional benchmarks included comparing the performance of fields, properties, and indexers. In most cases, simple syntactic sugar does not add overhead to the performance. However, using properties and indexers through a field inside an instanced method seems to add overhead. The overhead could be removed by storing the target object in a local variable before the loop. Storing the target object in a local variable removes the need to load it from a field during each iteration.
In this thesis, we performed benchmarks to determine the performance effects of high-level changes. In addition to benchmarks, we inspected the changes on the bytecode level. The benchmark methods iterate over a sequence of elements, counting the sum of all elements. We started by comparing the performance differences between arrays and lists. The list showed a small overhead in most cases and a noticeable overhead in some cases. Because the generic list contains different implementation details, we performed additional benchmarks on the used syntactic sugar. The additional benchmarks included comparing the performance of fields, properties, and indexers. In most cases, simple syntactic sugar does not add overhead to the performance. However, using properties and indexers through a field inside an instanced method seems to add overhead. The overhead could be removed by storing the target object in a local variable before the loop. Storing the target object in a local variable removes the need to load it from a field during each iteration.