Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance question #66

Open
iganinja opened this issue Aug 24, 2015 · 4 comments
Open

Performance question #66

iganinja opened this issue Aug 24, 2015 · 4 comments

Comments

@iganinja
Copy link

Hi

I am currently programming a small home brew game and I plan to use Lua along with Sol. My idea is to somewhat use the model exposed by Unity and other game developing packages: the game entities (for example a zombie enemy) will be formed by different components (sprite or graphical representation, collider, etc). These components will be managed by the C++ part, while Lua will be "the client": it just asks for a collider, a sprite, etc. and uses them in some coherent way (for example collider determines the world position of the sprite). This is somewhat analog to how javascript deals with DOM objects provided by the browser.

So to implement that I thought I could create, to expose to Lua, a bunch of functions like the following:

std::size_t newSprite(const std::string& fileName);
void setSpritePosition(std::size_t spriteId, const Vector2D& position);
void removeSprite(std::size_t spriteId);

These functions would be implemented in order to call SpriteController, which with the spriteId would look up in its sprite list and modify the corresponding sprite object.

But on the other hand I can also expose C++ classes to Lua, for example:

class SpriteLua
{
public:
    Sprite(const std::string& fileName)
    {
        mSprite = spriteController.load(fileName);
    }

    void setPosition(const Vector2D& position)
    {
        mSprite->setPosition(position);
    }
    ...
    ...
private:
    Sprite* mSprite;
};

The class approach seems faster and also more convenient to write in the Lua side (just manage Sprite instance instead of spriteSomething + spriteId + parameters, but I don't know the overhead, if it exists at all, of this second approach.

I know this can be a premature optimization case but I think I need to know both approach relative cost, it can decide how to do a substantial part of C++ <--> Lua communication of the game. Also I welcome any other suggestion about this or related issue.

Thanks

@ThePhD
Copy link
Contributor

ThePhD commented Aug 25, 2015

I am currently busy with a few other things so I can't check this right now.

Intuition tells me that just hooking up a bunch of free functions where you take a pointer value or an index value will be the absolute cheapest thing you can do. Note that if you do use a free function you also need to send additional information about where to get the real sprite value (if you use an index like your report suggests).

On a broader scope, this question is important because I have not taken the time to sit down and measure the impact that sol might have as a "wrapper" over lua. Most everything should have no overhead, except for:

  • setting stateful functions (lambdas that capture state)
  • usertype creation (and overloaded metamethods)

Those are about the only things that have actual data and code overhead that may be measurable. Non-stateful functions are reduced to function pointers where possible. And, setting/getting values from lua uses only templates and compile-time tricks as to be easily optimized out on either VC++ or g++/clang++, so I'm not worried about that.

It will take me a while to write appropriate performance tests for usertypes and stateful functions, as well as the rest of the API. My gut feeling is that -- especially if you use luaJIT -- there will be no overhead that'll affect you no matter which approach you take.

@iganinja
Copy link
Author

Hi ThePhD, thanks for the answer.

So if I understood correctly, if I don't create new types while the game is running it should be OK in any of the two ways presented in the first post. I will then use the second approach.

By the way I am not using luaJIT, would it be hard to use it instead of the normal lua? Is the performance difference really big?

Thanks again.

@ThePhD
Copy link
Contributor

ThePhD commented Aug 26, 2015

I can safely say, @iganinja, that luajit is THE way to speed up any lua runtime. It comes with the cost of knowing how to compile it for your platforms, but luajit is the sole reason why you can run huge, complex projects with a source-compatible API that allows massive speedups at the lowest levels possible, without having to rewrite really any code.

Support for luajit is currently experimental in sol, and while I do have a branch with a pull request for it it's not Officially Supported™ by sol.

The second approach should be fine, but it will cost you extra memory for keeping a lua userdata around to call those functions. The other approach technically takes less memory, but requires a small amount of indirection to get the sprite pointer from the index everytime.

Good luck.

@iganinja
Copy link
Author

Hi again @ThePhD

I will take the second route as said in the previous post and use the normal, "vanilla" Lua. After some time sol support for LuaJIT will be available and I could change to it without problem in lua and sol code.

Thanks again for everything and for sol :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants