Advertisement

Very slow loading of bytecode on iOS

Started by June 18, 2015 03:41 PM
13 comments, last by WitchLord 9 years, 4 months ago

Hi!

Currently we optimizing loading time of our application. Now 11 seconds needed to start application. After profiling we found that approximately 3 seconds needed to load byte code. According profile almost all time was spended in asCReader::Reader(bool*). More details are visible on screenshot - http://rghost.ru/7sxkVzWv8

It is possible to speed up loading of byte code? Loading speed are very critical to us and without your help we can't achieve satisfying result.

From the screenshot it looks like most of the time with loading the bytecode is spent in the function asCReader::ReadUsedFunctions, more specifically with the calls to IsSignatureEqual.

A trivial optimization would be to switch the order of the comparisons in the conditions. For example:

    for( asUINT i = 0; i < engine->scriptFunctions.GetLength(); i++ )
    {
     asCScriptFunction *f = engine->scriptFunctions[i];
     if( f == 0 ||
      !func.IsSignatureEqual(f) ||                        // <-- make this the last check in the condition, since it is the most expensive
      func.objectType != f->objectType ||
      func.nameSpace != f->nameSpace )
      continue;
     usedFunctions[n] = f;
     break;
    }

Going a bit further but still keeping it simple, I would look into rearranging the logic inside IsSignatureEqual(). For example:

bool asCScriptFunction::IsSignatureEqual(const asCScriptFunction *func) const
{
 if( !IsSignatureExceptNameEqual(func) || name != func->name ) return false;  // <-- change this so the name is compared first
 return true;
}

Just these two simple changes has the potential of saving 1-2 seconds on your loading time.

Would you mind making the above changes and verifying if the improvement is worth it? If it is I'll have the changes checked in to the SVN for the next release.

A much more complex optimization can be done by storing the functions in a hash map so the lookup done in ReadUsedFunctions() isn't done linearly. This would require a considerable amount of work, and I'm not entirely sure how much time it would save (though I'd guess it would be in the range of 80% of the time).

If the trivial changes I proposed above are good enough, then it will probably not be worth it to spend this time to implement the hash map.

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

Advertisement

Hi!

Yep, suggested changes did the job. Now on Iphone 5 loading time are about 8.5 seconds.

Thank you for help.

Great, I'll have the changes checked in. biggrin.png

Can you show me a new profiling screenshot so I can see what the current bottleneck for loading bytecode is?

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

I've checked in the improvement in revision 2183.

Regards,

Andreas

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

Hi!

This is new profiling screenshoot - http://rghost.ru/8Qg8RRqSS

Looks like ReadUsedFunctions are heavy by itself.

Advertisement

Indeed. The only way that this function can use up nearly 2 seconds by itself is if you have a lot of functions in the different arrays.

Can you show me how large each of the arrays that the function loops over are? It will help me understand better where to focus my efforts on optimizing the code.

usedFunctions.GetLength();
module->bindInformations.GetLength(); 
module->scriptFunctions.GetLength();
engine->scriptFunctions.GetLength();

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

Sorry for late answer.

usedFunctions.GetLength(); is equal 3010

module->bindInformations.GetLength(); is equal 0

module->scriptFunctions.GetLength(); is equal 2832

engine->scriptFunctions.GetLength(); is equal 22835

I hope this info will help

It does indeed.

You have far more functions in the engine->scriptFunctions array than I had expected. Even the size of module->scriptFunctions.GetLength() is larger than I had thought.

The linear search currently implemented in ReadUsedFunctions is definitely not good enough in this case. With your scenario the code could be doing as many as 68,733,350 comparisons (worst case) to find the correct function id for each of the used functions, which understandably takes a while to compute on mobile devices.

I'll work on improving this logic for the next release. Will let you know when it is available in the SVN.

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

Thank you.

I look forward for update :)

This topic is closed to new replies.

Advertisement