Lua / C++ boundary performance

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Lua / C++ boundary performance

      In a few of these posts, I talked about the Lua / C++ boundary and the costs associated with with. I said that calling a C++ function from Lua is generally slow so you only want to do it if the speed boost of having the C++ function outweighs the overhead of crossing that boundary. I also said the same thing for going from C++ to Lua.

      Well, I'm in the middle of overhauling my scripting paradigm and decided to actually measure the performance. I was rather surprised at some of the results. Let's start with Lua calling a C++ function. Here's the test code:

      Source Code

      1. function PerformanceTest()
      2. local numIterations = 10000000;
      3. local startTime = 0;
      4. local executionTime = 0;
      5. -- Lua
      6. startTime = os.clock();
      7. for i = 1, numIterations do
      8. LuaFunctionCall();
      9. end
      10. executionTime = os.clock() - startTime;
      11. print("Lua: " .. executionTime);
      12. -- C++
      13. startTime = os.clock();
      14. for i = 1, numIterations do
      15. CFunctionCall();
      16. end
      17. executionTime = os.clock() - startTime;
      18. print("C++: " .. executionTime);
      19. end
      Display All


      As you can see, it just calls a Lua function 10,000,000 times and times it, then does the same thing with a C++ function. Since I'm measuring overhead, I implemented trivial functions:

      Source Code

      1. -- Here's the Lua one
      2. function LuaFunctionCall()
      3. return 0;
      4. end
      5. // here's the C++ one
      6. int CFunctionCallForLuaPerformance(void)
      7. {
      8. return 0;
      9. }


      The results were rather interesting. In debug mode, calling the C++ function was about 1.7 times slower than the Lua function. This is about what I expected. However, when I did the same test in release mode, the C++ function call ended up being slightly faster! The Lua method was about 1.16 times as slow as the C++ method call.

      So, it looks like I lied. Calling a C++ function from Lua is actually faster than calling a regular Lua function. Keep in mind that this is using LuaPlus. If you're using something else (like luabind), these timings will likely be different.

      The second test I did was from C++ to Lua. I did the same test and ran the timer, but it didn't really matter. I kept getting a result of 0 for the C++ function since the compiler stripped it out in release mode. In debug mode, calling into Lua was about 17 times slower than calling the C++ function.

      I decided to devise a more real test. I wrote a square function in Lua and another in C++. Here's the C++ version:

      Source Code

      1. int TestPerformanceSquare(int val)
      2. {
      3. return val * val;
      4. }


      The Lua function is exactly the same. This is an interesting test that will skew a bit in C++'s favor since there's work being done inside the body of the function, but it should still give us a ball park figure.

      The results were staggering. Calling into Lua and running the square function was about 130 times slower than just calling the C++ function. It took about 97ms to call the C++ square function 100,000,000 times. Calling down into Lua 100,000,000 times took nearly 13 seconds. Wow.

      So, in conclusion, calling from Lua to C++ is great. Calling from C++ down to Lua is terrible, and you should do it as infrequently as possible. For those of you using Lua update functions that are meant to be called each frame, I would strongly suggest writing a single Heartbeat() function that's called from C++ once per frame and having that function call all of your updates. That's MUCH faster than having C++ call each update individually.

      -Rez