Browser hacking: Let's hack on the JIT until ai-astar.js SINGS
TLDRIn this video, the presenter focuses on optimizing the JavaScript Just-In-Time (JIT) compiler to improve performance on the Kraken AI A* test from the Kraken Benchmark suite. They demonstrate a significant speedup by implementing fast paths for equality checks between objects and handling the 'length' property of arrays more efficiently. The presenter profiles the code, identifies bottlenecks, and discusses the importance of caching and avoiding unnecessary calls to C++. The result is an impressive reduction in execution time from 2.15 seconds to 870 milliseconds, showcasing the potential for further optimization in JIT compilation.
Takeaways
- 😀 The video focuses on optimizing the JavaScript Just-In-Time (JIT) compiler to improve performance in the Kraken AI A* test.
- 🔍 The initial test without JIT took around 7.3 seconds, while with JIT enabled, it reduced to approximately 2.3 seconds, showcasing significant progress.
- 🚀 The goal is to further optimize the JIT to make the test run as fast as possible, aiming for all execution to occur in jitted code for optimal speed.
- 🔧 Profiling revealed that a considerable amount of time was spent in C++ helpers, particularly in the 'Loosely equals' function, indicating a need for optimization.
- 🛠️ The 'Loosely equals' operator was identified as a bottleneck and a candidate for a fast path in the JIT, as it's a common operation in JavaScript.
- 🔄 After implementing a fast path for object equality checks, the test time improved from 2.35 seconds to 2.15 seconds, a 10% improvement.
- 📈 Further profiling showed that 'get by ID' and property access on arrays were still heavy, suggesting more areas for optimization.
- 💡 A fast path for 'array.length' was implemented, recognizing that it's a common and magical property in JavaScript that reflects the number of elements.
- ⏱️ The addition of the 'array.length' fast path resulted in a massive speed up, reducing the test time from 2.15 seconds to 870 milliseconds.
- 📊 The final profile showed 85.7% of the runtime spent in generated JIT code, with less than 15% in C++, indicating a successful optimization.
- 🌟 The presenter expressed satisfaction with the progress but acknowledged that there's still room for improvement and other tests to optimize in the future.
Q & A
What is the main focus of the video?
-The main focus of the video is optimizing the JavaScript Just-In-Time (JIT) compiler to improve performance, specifically targeting the Kraken AI A* test.
What benchmark test is being used in the video?
-The benchmark test being used is the Kraken AI A* test from the Kraken Benchmark.
How much time did the test take without enabling the JIT?
-Without enabling the JIT, the test took approximately 7.3 seconds.
How much time did the test take with the JIT enabled?
-With the JIT enabled, the test time reduced to approximately 2.3 seconds.
What is one of the major performance bottlenecks identified in the JIT machine code?
-One major performance bottleneck identified is the heavy use of the 'Loosely equals' operator, which is the '==' operator in JavaScript.
What approach is suggested to optimize the 'Loosely equals' operator?
-The suggested approach is to create a fast path for equality checking in the JIT for common cases, especially for object comparisons.
What is the expected outcome after implementing the fast path for 'Loosely equals'?
-The expected outcome is a performance improvement, reducing the test time by about 10%.
What additional fast path is implemented to further optimize performance?
-An additional fast path is implemented for the 'length' property of arrays, which is a common operation in JavaScript.
What is the performance improvement achieved after implementing both fast paths?
-After implementing both fast paths, the test time reduced to approximately 870 milliseconds, a significant improvement from the initial 7.3 seconds.
What future optimizations are suggested in the video?
-Future optimizations include implementing fast paths for other equality-related operators and handling property additions more efficiently during setup code.
Outlines
🚀 JavaScript JIT Optimization
The script discusses enhancing the JavaScript Just-In-Time (JIT) compiler performance by revisiting the Kraken AIA* test from the Kraken Benchmark suite. The presenter demonstrates the current performance of the Bode interpreter without JIT, which takes around 7.3 seconds, and then shows a significant speed-up with JIT enabled, reducing the time to approximately 2.3 seconds. The goal is to profile the test, identify bottlenecks, and optimize the JIT to further improve performance. The A* pathfinding algorithm's grid setup and search process are highlighted, and the presenter expresses intent to explore fast paths in the JIT to optimize the test.
🔍 Profiling and Identifying Bottlenecks
In this paragraph, the focus is on profiling the JavaScript code to find performance bottlenecks. The presenter uses Callgrind to identify that about 30% of the runtime is already in JIT machine code, but there are still calls to C++ for certain operations, such as 'Loosely equals'. It's revealed that 'Loosely equals' is essentially delegating to 'strictly equals', and the presenter considers creating a fast path for equality checks, which are common in JavaScript, to improve performance.
🛠️ Implementing Fast Paths for Equality Checks
The presenter decides to implement a fast path for the 'Loosely equals' operation, which is a significant performance bottleneck. They modify the JIT to handle equality checks between objects more efficiently by doing an identity comparison when both sides are objects. After implementing this change, a performance improvement is observed, reducing the test time from 2.35 seconds to 2.15 seconds, which is a 10% improvement.
🔧 Further Optimizations and Testing
The script continues with further optimization efforts. The presenter identifies that 'get by ID' and property access on arrays are still causing performance issues. They discuss the implementation of a fast path for array access and the caching mechanism for 'get by ID'. After making these changes, they verify that the optimizations have not broken any functionality and observe a significant reduction in test time, from 2.15 seconds to 870 milliseconds.
🌐 Special Handling for Array Length
The focus shifts to optimizing access to the 'length' property of arrays, which is a common operation in JavaScript. The presenter identifies that the current implementation of getting the 'length' property is not using the fast path due to special handling in the code. They propose adding a flag to objects to indicate the presence of a 'magical length property' and modifying the JIT to check for this flag, allowing for a faster path when accessing the 'length' property of arrays.
🎯 Committing Changes and Further Profiling
After implementing the fast path for array length, the presenter commits the changes and profiles the test again. They observe a massive speed-up, reducing the test time from 2.15 seconds to 870 milliseconds. The profile shows that 85.7% of the time is spent in the generated JIT code, indicating a significant improvement. However, there are still some operations in C++ that could be optimized, such as call frame setups and property setting.
🔄 Addressing Parser Performance and Future Optimizations
The presenter notes that parser performance is now visible in the profile, suggesting that there is room for optimization in the parsing process. They also discuss the possibility of optimizing the 'splice' method and combining 'has property' checks with 'get' operations. However, they decide not to make changes at this time and consider these potential optimizations for the future.
🏁 Wrapping Up and Future Outlook
In the final paragraph, the presenter expresses satisfaction with the progress made in optimizing the JIT compiler. They highlight the simplicity and effectiveness of the changes made and suggest that there is still much work to be done, with many other tests and benchmarks to optimize. They also encourage ongoing contributions to the JIT compiler project and look forward to further improvements.
Mindmap
Keywords
💡JavaScript JIT
💡Kraken Benchmark
💡AIA STAR test
💡Bode Interpreter
💡Profiling
💡Loosely Equals
💡C++ Helpers
💡Fast Path
💡Array Property Access
💡Internal Get Own Property
💡Optimizing Compiler
Highlights
The video focuses on optimizing JavaScript JIT (Just-In-Time) compilation for the Kraken AIA* test.
The Bode interpreter's performance without JIT is compared to the significantly faster JIT-enabled execution.
JIT has made substantial progress, but there is still room for performance improvement.
Profiling is used to identify bottlenecks in the JIT compilation process.
The A* pathfinding algorithm is the core of the Kraken AIA* test, simulating grid-based searches.
The video discusses the importance of optimizing the 'loose equals' operation in JavaScript.
A fast path for equality checking is proposed to improve the performance of common JavaScript operations.
Debug output is enhanced to better understand the comparison operations in the test.
The video demonstrates a 10% performance improvement after implementing a fast path for object identity comparison.
Further profiling reveals issues with array property access and the need for optimization.
The special handling of 'array.length' is identified as a potential caching problem.
A fast path for 'array.length' is implemented to avoid unnecessary property lookups.
The video shows a massive speedup after the 'array.length' optimization, reducing test time from 2.15s to 0.87s.
The new profile shows 85.7% of self time in generated JIT code, indicating a successful optimization.
Remaining performance issues include calls to C++ for certain operations, such as 'put by ID'.
The video concludes by acknowledging the need for further optimizations in other areas of the JIT compiler.
The presenter expresses satisfaction with the progress made and enthusiasm for continuing work on the JIT compiler.