skip to main content

AST vs. Bytecode: Interpreters in the Age of Meta-Compilation

Published:16 October 2023Publication History
Skip Abstract Section

Abstract

Thanks to partial evaluation and meta-tracing, it became practical to build language implementations that reach state-of-the-art peak performance by implementing only an interpreter. Systems such as RPython and GraalVM provide components such as a garbage collector and just-in-time compiler in a language-agnostic manner, greatly reducing implementation effort.

However, meta-compilation-based language implementations still need to improve further to reach the low memory use and fast warmup behavior that custom-built systems provide. A key element in this endeavor is interpreter performance. Folklore tells us that bytecode interpreters are superior to abstract-syntax-tree (AST) interpreters both in terms of memory use and run-time performance.

This work assesses the trade-offs between AST and bytecode interpreters to verify common assumptions and whether they hold in the context of meta-compilation systems. We implemented four interpreters, each an AST and a bytecode one using RPython and GraalVM. We keep the difference between the interpreters as small as feasible to be able to evaluate interpreter performance, peak performance, warmup, memory use, and the impact of individual optimizations.

Our results show that both systems indeed reach performance close to Node.js/V8. Looking at interpreter-only performance, our AST interpreters are on par with, or even slightly faster than their bytecode counterparts. After just-in-time compilation, the results are roughly on par. This means bytecode interpreters do not have their widely assumed performance advantage. However, we can confirm that bytecodes are more compact in memory than ASTs, which becomes relevant for larger applications. However, for smaller applications, we noticed that bytecode interpreters allocate more memory because boxing avoidance is not as applicable, and because the bytecode interpreter structure requires memory, e.g., for a reified stack.

Our results show AST interpreters to be competitive on top of meta-compilation systems. Together with possible engineering benefits, they should thus not be discounted so easily in favor of bytecode interpreters.

Skip Supplemental Material Section

Supplemental Material

References

  1. John Aycock. 2003. A Brief History of Just-In-Time. ACM Comput. Surv., 35, 2 (2003), June, 97–113. issn:0360-0300 https://doi.org/10.1145/857076.857077 Google ScholarGoogle ScholarDigital LibraryDigital Library
  2. Vasanth Bala, Evelyn Duesterwald, and Sanjeev Banerjia. 2000. Dynamo: A Transparent Dynamic Optimization System. In Proceedings of the ACM SIGPLAN 2000 Conference on Programming Language Design and Implementation (PLDI ’00). ACM, 1–12. isbn:1-58113-199-2 https://doi.org/10.1145/358438.349303 Google ScholarGoogle ScholarDigital LibraryDigital Library
  3. Edd Barrett, Carl Friedrich Bolz-Tereick, Rebecca Killick, Sarah Mount, and Laurence Tratt. 2017. Virtual Machine Warmup Blows Hot and Cold. Proc. ACM Program. Lang., 1, OOPSLA (2017), Article 52, Oct., 27 pages. issn:2475-1421 https://doi.org/10.1145/3133876 Google ScholarGoogle ScholarDigital LibraryDigital Library
  4. James R. Bell. 1973. Threaded Code. Commun. ACM, 16, 6 (1973), June, 370–372. issn:0001-0782 https://doi.org/10.1145/362248.362270 Google ScholarGoogle ScholarDigital LibraryDigital Library
  5. Carl Friedrich Bolz, Antonio Cuni, Maciej Fijalkowski, and Armin Rigo. 2009. Tracing the Meta-level: PyPy’s Tracing JIT Compiler. In Proceedings of the 4th Workshop on the Implementation, Compilation, Optimization of Object-Oriented Languages and Programming Systems (ICOOOLPS ’09). ACM, 18–25. isbn:978-1-60558-541-3 https://doi.org/10.1145/1565824.1565827 Google ScholarGoogle ScholarDigital LibraryDigital Library
  6. Carl Friedrich Bolz, Lukas Diekmann, and Laurence Tratt. 2013. Storage Strategies for Collections in Dynamically Typed Languages. In Proceedings of the 2013 ACM SIGPLAN International Conference on Object Oriented Programming Systems Languages & Applications (OOPSLA ’13). ACM, 167–182. isbn:978-1-4503-2374-1 https://doi.org/10.1145/2509136.2509531 Google ScholarGoogle ScholarDigital LibraryDigital Library
  7. Carl Friedrich Bolz and Laurence Tratt. 2013. The Impact of Meta-Tracing on VM Design and Implementation. Science of Computer Programming, 98 (2013), 408–421. issn:0167-6423 https://doi.org/10.1016/j.scico.2013.02.001 Google ScholarGoogle ScholarDigital LibraryDigital Library
  8. Stefan Brunthaler. 2010. Efficient Interpretation Using Quickening. In Proceedings of the 6th Symposium on Dynamic Languages (DLS’10, 12). ACM, 1–14. issn:0362-1340 https://doi.org/10.1145/1899661.1869633 Google ScholarGoogle ScholarDigital LibraryDigital Library
  9. Stefan Brunthaler. 2010. Inline Caching Meets Quickening. In ECOOP 2010 – Object-Oriented Programming, Theo D’Hondt (Ed.). 6183, Springer, 429–451. isbn:978-3-642-14107-2 https://doi.org/10.1007/978-3-642-14107-2_21 Google ScholarGoogle ScholarCross RefCross Ref
  10. Stefan Brunthaler. 2021. Multi-Level Quickening: Ten Years Later. CoRR, abs/2109.02958 (2021), 47 pages. arXiv:2109.02958. arxiv:2109.02958 Google ScholarGoogle Scholar
  11. Craig Chambers, David Ungar, and Elgin Lee. 1989. An Efficient Implementation of SELF a Dynamically-Typed Object-Oriented Language Based on Prototypes. In Proceedings on Object-Oriented Programming Systems, Languages and Applications (OOPSLA). ACM, 49–70. isbn:0-89791-333-7 issn:0362-1340 https://doi.org/10.1145/74878.74884 Google ScholarGoogle ScholarDigital LibraryDigital Library
  12. Theo D’Hondt. 2008. Are Bytecodes an Atavism? In Self-Sustaining Systems, Robert Hirschfeld and Kim Rose (Eds.) (Lecture Notes in Computer Science, Vol. 5146). Springer, 140–155. isbn:978-3-540-89274-8 https://doi.org/10.1007/978-3-540-89275-5_8 Google ScholarGoogle ScholarDigital LibraryDigital Library
  13. M. Anton Ertl. 1995. Stack Caching for Interpreters. In Proceedings of the ACM SIGPLAN 1995 Conference on Programming Language Design and Implementation (PLDI’95). ACM, 315–327. issn:0362-1340 https://doi.org/10.1145/207110.207165 Google ScholarGoogle ScholarDigital LibraryDigital Library
  14. M. Anton Ertl and David Gregg. 2003. The Structure and Performance of Efficient Interpreters. Journal of Instruction-Level Parallelism, 5 (2003), November, 1–25. http://www.jilp.org/vol5/v5paper12.pdf Google ScholarGoogle Scholar
  15. Yoshihiko Futamura. 1999, Originally published in 1971. Partial Evaluation of Computation Process–An Approach to a Compiler-Compiler. Higher-Order and Symbolic Computation, 12, 4 (1999, Originally published in 1971), 381–391. issn:1388-3690 https://doi.org/10.1023/A:1010095604496 Google ScholarGoogle ScholarDigital LibraryDigital Library
  16. Andreas Gal, Christian W. Probst, and Michael Franz. 2006. HotpathVM: An Effective JIT Compiler for Resource-constrained Devices. In Proceedings of the 2nd International Conference on Virtual Execution Environments (VEE’06). ACM, 144–153. isbn:1-59593-332-6 https://doi.org/10.1145/1134760.1134780 Google ScholarGoogle ScholarDigital LibraryDigital Library
  17. Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. 1994. Design Patterns: Elements of Reusable Object-Oriented Software (1st ed.). Addison-Wesley Professional. isbn:978-0201633610 Google ScholarGoogle ScholarDigital LibraryDigital Library
  18. Matthias Grimmer, Roland Schatz, Chris Seaton, Thomas Würthinger, Mikel Luján, and Hanspeter Mössenböck. 2018. Cross-Language Interoperability in a Multi-Language Runtime. ACM Transactions on Programming Languages and Systems, 40, 2 (2018), June, 1–43. https://doi.org/10.1145/3201898 Google ScholarGoogle ScholarDigital LibraryDigital Library
  19. Michael Haupt, Robert Hirschfeld, Tobias Pape, Gregor Gabrysiak, Stefan Marr, Arne Bergmann, Arvid Heise, Matthias Kleine, and Robert Krahn. 2010. The SOM Family: Virtual Machines for Teaching and Research. In Proceedings of the 15th Annual Conference on Innovation and Technology in Computer Science Education (ITiCSE’10). ACM, 18–22. isbn:978-1-60558-729-5 https://doi.org/10.1145/1822090.1822098 Google ScholarGoogle ScholarDigital LibraryDigital Library
  20. Christian Humer and Nikola Bebić. 2022. Operation DSL: How We Learned to Stop Worrying and Love Bytecodes again.. https://2022.ecoop.org/details/truffle-2022/3/Operation-DSL-How-We-Learned-to-Stop-Worrying-and-Love-Bytecodes-again Truffle Workshop ’22, Presentation Google ScholarGoogle Scholar
  21. Christian Humer, Christian Wimmer, Christian Wirth, Andreas Wöß, and Thomas Würthinger. 2014. A Domain-Specific Language for Building Self-Optimizing AST Interpreters. In Proceedings of the 13th International Conference on Generative Programming: Concepts and Experiences (GPCE ’14). ACM, 123–132. isbn:978-1-4503-3161-6 https://doi.org/10.1145/2658761.2658776 Google ScholarGoogle ScholarDigital LibraryDigital Library
  22. Urs Hölzle, Craig Chambers, and David Ungar. 1991. Optimizing Dynamically-Typed Object-Oriented Languages With Polymorphic Inline Caches. In ECOOP ’91: European Conference on Object-Oriented Programming (LNCS, Vol. 512). Springer, 21–38. isbn:3-540-54262-0 https://doi.org/10.1007/BFb0057013 Google ScholarGoogle ScholarCross RefCross Ref
  23. Yusuke Izawa, Hidehiko Masuhara, Carl Friedrich Bolz-Tereick, and Youyou Cong. 2022. Threaded Code Generation with a Meta-Tracing JIT Compiler. Journal of Object Technology, 21, 2 (2022), 2:1–11. issn:1660-1769 https://doi.org/10.5381/jot.2022.21.2.a1 Google ScholarGoogle ScholarCross RefCross Ref
  24. Sophie Kaleba, Octave Larose, Richard Jones, and Stefan Marr. 2022. Who You Gonna Call: Analyzing the Run-time Call-Site Behavior of Ruby Applications. In Proceedings of the 18th Symposium on Dynamic Languages (DLS’22). ACM, 14. https://doi.org/10.1145/3563834.3567538 Google ScholarGoogle ScholarDigital LibraryDigital Library
  25. Tomas Kalibera, Petr Maj, Floreal Morandat, and Jan Vitek. 2014. A Fast Abstract Syntax Tree Interpreter for R. In Proceedings of the 10th ACM SIGPLAN/SIGOPS International Conference on Virtual Execution Environments (VEE’14). ACM, 89–102. isbn:978-1-4503-2764-0 https://doi.org/10.1145/2576195.2576205 Google ScholarGoogle ScholarDigital LibraryDigital Library
  26. Chaitanya Koparkar, Mike Rainey, Michael Vollmer, Milind Kulkarni, and Ryan R. Newton. 2021. Efficient Tree-Traversals: Reconciling Parallelism and Dense Data Representations. Proceedings of the ACM on Programming Languages, 5, ICFP (2021), Aug., 1–29. https://doi.org/10.1145/3473596 Google ScholarGoogle ScholarDigital LibraryDigital Library
  27. Philipp Körner, David Schneider, and Michael Leuschel. 2021. On the Performance of Bytecode Interpreters in Prolog. In Functional and Constraint Logic Programming: 28th International Workshop, WFLP 2020 (WFLP’20, Vol. 12560). Springer, 41–56. isbn:978-3-030-75333-7 https://doi.org/10.1007/978-3-030-75333-7_3 Google ScholarGoogle ScholarCross RefCross Ref
  28. Octave Larose, Sophie Kaleba, Humphrey Burchell, and Stefan Marr. 2023. AST vs. Bytecode: Interpreters in the Age of Meta-Compilation (Artifact). https://doi.org/10.5281/zenodo.8333815 Google ScholarGoogle ScholarDigital LibraryDigital Library
  29. Octave Larose, Sophie Kaleba, and Stefan Marr. 2022. Less Is More: Merging AST Nodes To Optimize Interpreters. MoreVMs ’22 Workshop, Presentation Google ScholarGoogle Scholar
  30. Stefan Marr. 2023. ReBench: Execute and Document Benchmarks Reproducibly.. https://doi.org/10.5281/zenodo.1311762 Version 1.2 Google ScholarGoogle ScholarCross RefCross Ref
  31. Stefan Marr, Benoit Daloze, and Hanspeter Mössenböck. 2016. Cross-Language Compiler Benchmarking—Are We Fast Yet? In Proceedings of the 12th Symposium on Dynamic Languages (DLS’16). ACM, 120–131. isbn:978-1-4503-4445-6 https://doi.org/10.1145/2989225.2989232 Google ScholarGoogle ScholarDigital LibraryDigital Library
  32. Stefan Marr and Stéphane Ducasse. 2015. Tracing vs. Partial Evaluation: Comparing Meta-Compilation Approaches for Self-Optimizing Interpreters. In Proceedings of the 2015 ACM International Conference on Object Oriented Programming Systems Languages & Applications (OOPSLA ’15). ACM, 821–839. isbn:978-1-4503-2585-1 https://doi.org/10.1145/2814270.2814275 Google ScholarGoogle ScholarDigital LibraryDigital Library
  33. Fabio Niephaus, Tim Felgentreff, and Robert Hirschfeld. 2018. GraalSqueak: A Fast Smalltalk Bytecode Interpreter Written in an AST Interpreter Framework. In Proceedings of the 13th Workshop on Implementation, Compilation, Optimization of Object-Oriented Languages, Programs and Systems (ICOOOLPS’18). ACM, 30–35. https://doi.org/10.1145/3242947.3242948 Google ScholarGoogle ScholarDigital LibraryDigital Library
  34. G. Ottoni and B. Liu. 2021. HHVM Jump-Start: Boosting Both Warmup and Steady-State Performance at Scale. In 2021 IEEE/ACM International Symposium on Code Generation and Optimization (CGO). IEEE Computer Society, 340–350. https://doi.org/10.1109/CGO51591.2021.9370314 Google ScholarGoogle ScholarDigital LibraryDigital Library
  35. Tobias Pape. 2021. Efficient Compound Values in Virtual Machines. Universität Potsdam. https://doi.org/10.25932/publishup-49913 Google ScholarGoogle ScholarCross RefCross Ref
  36. Tobias Pape, Carl Friedrich Bolz, and Robert Hirschfeld. 2017. Adaptive Just-in-time Value Class Optimization for Lowering Memory Consumption and Improving Execution Time Performance. Science of Computer Programming, 140 (2017), 17–29. issn:0167-6423 https://doi.org/10.1016/j.scico.2016.08.003 Object-Oriented Programming and Systems (OOPS 2015) Google ScholarGoogle ScholarCross RefCross Ref
  37. Tobias Pape, Tim Felgentreff, Robert Hirschfeld, Anton Gulenko, and Carl Friedrich Bolz. 2015. Language-independent Storage Strategies for tracing-JIT-based Virtual Machines. In Proceedings of the 11th Symposium on Dynamic Languages (DLS 2015). ACM, 104–113. isbn:978-1-4503-3690-1 https://doi.org/10.1145/2816707.2816716 Google ScholarGoogle ScholarDigital LibraryDigital Library
  38. Ian Piumarta and Fabio Riccardi. 1998. Optimizing Direct-threaded Code by Selective Inlining. In Proceedings of the ACM SIGPLAN 1998 conference on Programming language design and implementation - PLDI ' 98. ACM, 291–300. https://doi.org/10.1145/277650.277743 Google ScholarGoogle ScholarDigital LibraryDigital Library
  39. Todd A. Proebsting. 1995. Optimizing an ANSI C interpreter with superoperators. In Proceedings of the 22nd ACM SIGPLAN-SIGACT symposium on Principles of programming languages - POPL ' 95. ACM Press, 322–332. https://doi.org/10.1145/199448.199526 Google ScholarGoogle ScholarDigital LibraryDigital Library
  40. Mohaned Qunaibit, Stefan Brunthaler, Yeoul Na, Stijn Volckaert, and Michael Franz. 2018. Accelerating Dynamically-Typed Languages on Heterogeneous Platforms Using Guards Optimization. In 32nd European Conference on Object-Oriented Programming (ECOOP 2018) (ECOOP’18, Vol. 109). Schloss Dagstuhl–Leibniz-Zentrum fuer Informatik, 16:1–16:29. isbn:978-3-95977-079-8 issn:1868-8969 https://doi.org/10.4230/LIPIcs.ECOOP.2018.16 Google ScholarGoogle ScholarCross RefCross Ref
  41. Yunhe Shi, Kevin Casey, M. Anton Ertl, and David Gregg. 2008. Virtual Machine Showdown: Stack Versus Registers. ACM Transactions on Architecture and Code Optimization, 4, 4 (2008), Jan., 1–36. issn:1544-3566 https://doi.org/10.1145/1328195.1328197 Google ScholarGoogle ScholarDigital LibraryDigital Library
  42. Ben L. Titzer. 2022. A Fast In-Place Interpreter for WebAssembly. Proceedings of the ACM on Programming Languages, 6, OOPSLA2 (2022), Oct., 646–672. https://doi.org/10.1145/3563311 Google ScholarGoogle ScholarDigital LibraryDigital Library
  43. Michael L. Van de Vanter, Chris Seaton, Michael Haupt, Christian Humer, and Thomas Würthinger. 2018. Fast, Flexible, Polyglot Instrumentation Support for Debuggers and other Tools. Programming Journal, 2, 3 (2018), March, 30. issn:2473-7321 https://doi.org/10.22152/programming-journal.org/2018/2/14 Google ScholarGoogle ScholarCross RefCross Ref
  44. Michael Vollmer, Sarah Spall, Buddhika Chamith, Laith Sakka, Chaitanya Koparkar, Milind Kulkarni, Sam Tobin-Hochstadt, and Ryan R. Newton. 2017. Compiling Tree Transforms to Operate on Packed Representations. In 31st European Conference on Object-Oriented Programming (ECOOP 2017) (Leibniz International Proceedings in Informatics (LIPIcs), Vol. 74). Schloss Dagstuhl–Leibniz-Zentrum fuer Informatik, 26:1–26:29. isbn:978-3-95977-035-4 issn:1868-8969 https://doi.org/10.4230/LIPIcs.ECOOP.2017.26 Google ScholarGoogle ScholarCross RefCross Ref
  45. Christian Wimmer, Codrut Stancu, Peter Hofer, Vojin Jovanovic, Paul Wögerer, Peter B. Kessler, Oleg Pliss, and Thomas Würthinger. 2019. Initialize Once, Start Fast: Application Initialization at Build Time. Proceedings of the ACM on Programming Languages, 3, OOPSLA (2019), Oct., 1–29. https://doi.org/10.1145/3360610 Google ScholarGoogle ScholarDigital LibraryDigital Library
  46. Andreas Wöß, Christian Wirth, Daniele Bonetta, Chris Seaton, Christian Humer, and Hanspeter Mössenböck. 2014. An Object Storage Model for the Truffle Language Implementation Framework. In Proceedings of the 2014 International Conference on Principles and Practices of Programming on the Java Platform: Virtual Machines, Languages, and Tools (PPPJ ’14). ACM, 133–144. isbn:978-1-4503-2926-2 https://doi.org/10.1145/2647508.2647517 Google ScholarGoogle ScholarDigital LibraryDigital Library
  47. Thomas Würthinger, Christian Wimmer, Christian Humer, Andreas Wöß, Lukas Stadler, Chris Seaton, Gilles Duboscq, Doug Simon, and Matthias Grimmer. 2017. Practical Partial Evaluation for High-performance Dynamic Language Runtimes. In Proceedings of the 38th ACM SIGPLAN Conference on Programming Language Design and Implementation (PLDI’17). ACM, 662–676. isbn:978-1-4503-4988-8 https://doi.org/10.1145/3062341.3062381 Google ScholarGoogle ScholarDigital LibraryDigital Library
  48. Thomas Würthinger, Christian Wimmer, Andreas Wöß, Lukas Stadler, Gilles Duboscq, Christian Humer, Gregor Richards, Doug Simon, and Mario Wolczko. 2013. One VM to Rule Them All. In Proceedings of the 2013 ACM International Symposium on New Ideas, New Paradigms, and Reflections on Programming & Software (Onward!’13). ACM, 187–204. isbn:978-1-4503-2472-4 https://doi.org/10.1145/2509578.2509581 Google ScholarGoogle ScholarDigital LibraryDigital Library
  49. Thomas Würthinger, Andreas Wöß, Lukas Stadler, Gilles Duboscq, Doug Simon, and Christian Wimmer. 2012. Self-Optimizing AST Interpreters. In Proceedings of the 8th Dynamic Languages Symposium (DLS’12). ACM, 73–82. isbn:978-1-4503-1564-7 https://doi.org/10.1145/2384577.2384587 Google ScholarGoogle ScholarDigital LibraryDigital Library
  50. Qiang Zhang, Lei Xu, and Baowen Xu. 2022. RegCPython: A Register-based Python Interpreter for Better Performance. ACM Transactions on Architecture and Code Optimization, 20, 1 (2022), Dec., 1–25. https://doi.org/10.1145/3568973 Google ScholarGoogle ScholarDigital LibraryDigital Library

Index Terms

  1. AST vs. Bytecode: Interpreters in the Age of Meta-Compilation

      Recommendations

      Comments

      Login options

      Check if you have access through your login credentials or your institution to get full access on this article.

      Sign in

      Full Access

      • Article Metrics

        • Downloads (Last 12 months)370
        • Downloads (Last 6 weeks)41

        Other Metrics

      PDF Format

      View or Download as a PDF file.

      PDF

      eReader

      View online with eReader.

      eReader