🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Refactoring suggestions

Started by
4 comments, last by WitchLord 8 years, 5 months ago

Hey Andreas, long time no see! Since it looks like we're in a refactoring spell, I'd humbly like to submit some suggestions for (breaking!) API changes that would improve performance, readability, or both. In no particular order:

  • Is there a reason why RegisterObjectProperty()/RegisterObjectMethod() live in asIScriptEngine rather than in asITypeInfo? Not only would this drastically improve performance for more complex application APIs, (as we don't need to repeatedly look up the type) but the error handling could be radically simplified as we don't need to handle cases where the name string doesn't refer to a previously registered type, etc. This seems like a no-brainer and it looks like most of the infrastructure is in place anyhow.
  • What's the consensus about pulling asCGarbageCollector or something similar into the public interface? While I don't know if this would be practical in the general case, my engine project currently can currently run multiple game worlds concurrently and it'd be nice to have them all run garbage collection in parallel with one another. Likewise, there would be fewer individual objects in each collection which would improve GC latency over what we have now.
  • Building off the prior idea, what if we move the CreateScriptObject() family of functions into the proposed asIGarbageCollector interface?
  • Looking up functions by name/signature is *super* yuck from a performance perspective. Could we perhaps hash a combination of the signature and argument type ids to avoid the mega-gross linear search through all registered functions in the type? Is it even possible for the multiple matching function case to occur in practice?

As a final, long-shot bit, what are the odds of moving the project over to GitHub? Things like pull requests become super-easy if you're interested in accepting more community contributions. It's pretty cool! smile.png

clb: At the end of 2012, the positions of jupiter, saturn, mercury, and deimos are aligned so as to cause a denormalized flush-to-zero bug when computing earth's gravitational force, slinging it to the sun.
Advertisement

All valid suggestions. Let me address them one by one:


Is there a reason why RegisterObjectProperty()/RegisterObjectMethod() live in asIScriptEngine rather than in asITypeInfo? Not only would this drastically improve performance for more complex application APIs, (as we don't need to repeatedly look up the type) but the error handling could be radically simplified as we don't need to handle cases where the name string doesn't refer to a previously registered type, etc. This seems like a no-brainer and it looks like most of the infrastructure is in place anyhow.

"Drastically improve performance" is probably drastically exaggerated, but I see your point. :)

I don't want to move the registration into the asITypeInfo interface as I want to keep it centralized in the engine interface. However, I should be able to do something about the performance anyway. I could for example cache the last used object type between calls, thus avoid the lookup most of the time. Or I could simply change it so that instead of passing the name of the object type, the asITypeInfo representing the type would be given by the application. I'll think about it.

Just how big is your application interface, since you're saying the performance is impacted by this? Can you perhaps send me the configuration file so I can take a look at it and perhaps do some performance tuning (create it with the WriteConfigToFile helper function)?


What's the consensus about pulling asCGarbageCollector or something similar into the public interface? While I don't know if this would be practical in the general case, my engine project currently can currently run multiple game worlds concurrently and it'd be nice to have them all run garbage collection in parallel with one another. Likewise, there would be fewer individual objects in each collection which would improve GC latency over what we have now.

I'm not sure what you're trying to get at here. Each engine instance keeps its own garbage collector, and you can already interact with it through the asIScriptEngine interface. What is it you feel is missing?

I'm always on the look-out for ways to improving the garbage collection. Ideally nothing would be stored in the garbage collector until it really is garbage and has to be collected, that way the garbage collector wouldn't have to do time consuming sweeps to try to identify if an object is garbage or a live object.

I have few ideas for improving the garbage collector already on my to-do list. Maybe I'll be able to try out some of those in 2016.


Building off the prior idea, what if we move the CreateScriptObject() family of functions into the proposed asIGarbageCollector interface?

No. CreateScriptObject has nothing to do with the garbage collector. The garbage collector doesn't even need to know about most objects, only those that can potentially form circular references.


Looking up functions by name/signature is *super* yuck from a performance perspective. Could we perhaps hash a combination of the signature and argument type ids to avoid the mega-gross linear search through all registered functions in the type? Is it even possible for the multiple matching function case to occur in practice?

Yes, looking up functions by name/signature is slow. That's why it is recommended to do it only once, and then keep the asIScriptFunction pointer. :)

How often do you look up functions by name/signature? Can you reduce the number of lookups by caching the result? How much time is your application spending on the look-ups?

There is always room for making improvements in the library. But there has to be really good argument for adding more complexity to the code and data-structure in order to speed up a few look-ups. Name-mangling might be possible, but there are other ways to speed up look-ups too.


As a final, long-shot bit, what are the odds of moving the project over to GitHub? Things like pull requests become super-easy if you're interested in accepting more community contributions. It's pretty cool!

You're not the first to suggest moving the project to GitHub :). However, I have not yet seen enough benefit to pursue this. It's not that I deny the usefulness of git pull requests, I just don't look forward to doing all the administrative work of moving the project over to GitHub, installing everything needed to use GitHub, learning those tools, etc. I imagine that I will eventually take the jump and move over to GitHub, but not now.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Is there a reason why RegisterObjectProperty()/RegisterObjectMethod() live in asIScriptEngine... <snip>


"Drastically improve performance" is probably drastically exaggerated, but I see your point. smile.png

I don't want to move the registration into the asITypeInfo interface as I want to keep it centralized in the engine interface. However, I should be able to do something about the performance anyway. I could for example cache the last used object type between calls, thus avoid the lookup most of the time. Or I could simply change it so that instead of passing the name of the object type, the asITypeInfo representing the type would be given by the application. I'll think about it.

Just how big is your application interface, since you're saying the performance is impacted by this? Can you perhaps send me the configuration file so I can take a look at it and perhaps do some performance tuning (create it with the WriteConfigToFile helper function)?


This is entirely fair. Startup time is actually very reasonable right now, but I'm a meganerd for application responsiveness. Your idea to take the asITypeInfo as a parameter seems a very acceptable compromise and I think I'd be happy with that. On the other hand, while I think understand your rationale for the caching idea, (common case for API registration is to create a type, then register all properties/methods on it-- worth noting I completely fall into this case) I would argue it's the inferior API decision considering it adds additional hidden state/inconsistent behavior. The parameter idea keeps the constant-time lookup and is less invasive of an source change.

What's the consensus about pulling asCGarbageCollector or something similar into the public interface? ... <snip>


I'm not sure what you're trying to get at here. Each engine instance keeps its own garbage collector, and you can already interact with it through the asIScriptEngine interface. What is it you feel is missing?

I'm always on the look-out for ways to improving the garbage collection. Ideally nothing would be stored in the garbage collector until it really is garbage and has to be collected, that way the garbage collector wouldn't have to do time consuming sweeps to try to identify if an object is garbage or a live object.

I have few ideas for improving the garbage collector already on my to-do list. Maybe I'll be able to try out some of those in 2016.


This was more along the conceptual lines of separating out script data (asITypeInfo/asIScriptModule), the stuff being scripted(asIScriptObjects on a micro level, and a notion of a hypothetical asIGarbageContext larger-scale), and the stuff executing scripts (asIScriptContexts/asIScriptEngine) into more distinctly scoped concepts. This one is definitely more out there in terms of direct feature usefulness, and revisiting this I'm not sure it's as attractive as I initially thought.

Looking up functions by name/signature is *super* yuck from a performance perspective ... <snip>


Yes, looking up functions by name/signature is slow. That's why it is recommended to do it only once, and then keep the asIScriptFunction pointer. smile.png

How often do you look up functions by name/signature? Can you reduce the number of lookups by caching the result? How much time is your application spending on the look-ups?

There is always room for making improvements in the library. But there has to be really good argument for adding more complexity to the code and data-structure in order to speed up a few look-ups. Name-mangling might be possible, but there are other ways to speed up look-ups too.


Very frequently. Current use case is something very similar to Theron whereupon all game events/application to script notifications are modeled as typed data structures sent to a (possibly overloaded) handler function. The caching solution you described was something I arrived at independently, but it just bothers me that maintaining a completely separate yet highly similar lookup system is necessary when some extensions to one would largely solve the problem.

clb: At the end of 2012, the positions of jupiter, saturn, mercury, and deimos are aligned so as to cause a denormalized flush-to-zero bug when computing earth's gravitational force, slinging it to the sun.

I see. So your application doesn't actually have any compile time knowledge of what script functions might be called.

Well, I can certainly look into speeding up the look-up of script functions in classes which might provide some performance boost in your case, however you should still consider caching to avoid unnecessary look-ups if possible.

Do you have any profiling stats for the look-ups in your application? How many look-ups are made on average per frame or second? How much time do these calls take in total and on average?

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

While it might be the least important thing in this discussion - I also think you should use GitHub. It is superior to SVN in many ways, even though I agree it might seem more complicated. But programs like GitHub Desktop have greatly reduced the complexity. I personally just don't like SourceForge as a site too (very cluttered) and that is more of a reason why I would like seeing AS on GitHub than actually SVN as source control. Also seeing commits and diff's are a lot easier on GitHub. While I'm trying to fix JIT compiler (still) I noticed that finding changes between AS versions are hard on SourceForge. Ended up downloading two commits and using Windows search to actually find if function is added or removed.

Windows search? Have you tried WinMerge. It's an excellent tool for comparing files on Windows.

I don't use SourceForge for it's web interface. I access the SVN directly using the svn client on Linux) or TortoiseSVN on Windows).

I have no doubt that GitHub would be just as easy to use, I just don't have any problem with SourceForge.net to really bother sitting down to actually do the work to migrate over to GitHub.

There are already mirrors of the AngelScript SVN on the GitHub that you can use if you prefer that over SourceForge.net.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement