Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upI18NBundle.createBundle takes unreasonable time on Android #2342
Comments
|
Well, unless you create one bundle per second I wouldn't say that 0.8 seconds make it close to unusable. :) |
|
Well, you are right. But during the game start of lot of things are usually loaded. Another second for nothing is a pity :) The simple hand-made solution with jsons do the same thing and consumes no time at all. Not sure how to profile third-party libraries on Android. Usually I just install own timers in a valuable places of my code. But what to do with a library? Can you give an idea? |
|
DDMS allows you to profile any code in your Android app.
|
|
Great. Thanks. Profile shows that all time is consumed by AnfroidFileHandle.exists(). Like I assumed before :) Therefore on Desktop you can not notice it. |
|
P.S. Because of this I use internally this function:
|
|
Hmmm.... It's a known issue.
|
|
Yes. And I guess this line about "very slow" in comments was introduced after my previous issue report :) That time I have even suggested to change the default implementation. My idea was to restrict .exists() only to files, excluding directories (the reason why it is so slow). Something like my function above. And make a separate function which includes directories. But the solution was to add a line in comments :) |
|
Yep more than 1 year ago https://code.google.com/p/libgdx/issues/detail?id=1655 |
|
What if just to remove the check if the bundle exists and try to load it directly? Then catch the exception, in the case it does not exists... (I18Bundle line 319). |
|
With your workaround a directory would be silently skipped and you won't get an exception. @badlogic @NathanSweet @MobiDevelop |
|
Using exceptions for flow control doesn't seem "right" but I guess it wouldn't be the end of the world. |
|
Yeah, I meant if we should fix this in I18NBundle or in FileHandle (providing an additional method or what else) |
|
I don't think we should change the behavior of the existing |
|
Additional exists is a bit meh, but the lesser of two evils...
|
|
Then how about adding /** Creates a stream for reading the specified file as bytes and ignore all errors.
* @return the input stream or {@code null} if the file handle represents a directory, doesn't exist, or could not be read. */
public static InputStream openQuietly (FileHandle fh) {
try {
return fh.read();
} catch (Throwable t) {
return null;
}
} |
|
I think any of the solutions will fit the current topic. However we will have this problem again next time. People would continue to use .exists since the problem is not wide-known and no one expect performance jam from such a simple function. At the same time I guess it is not good idea to change .exist behavior (despite I doubt that many people use it for directory check in the frame of libGDX). Probably the solution could be just to add a function with the name like .existsFastFileCheck. Then the people at least would see it automatically in autocomplition when they start to type .exists. |
|
@titovmaxim |
|
I'm not 100% sure (in a trip right now), but there is a difference between file.exists and FileHandle.exists. First one is ok, second one is slow. The second one is slow (if I remember correct, was a long time ago) just because if it fails with file.exists check, it tries to do FileHandle.class.getResource. (line 526 of FileHandle - fall through comment). It is done to assure correct check of directories. However in the comment of these function it is written that "On Android, a {@link FileType#Classpath} or {@link FileType#Internal} handle to a directory will always return false". So no reason for such slow check if should anyway return false. I'm a bit confused here. Probably just remove this last check only for android and internal files? Then it should work fast and according to the comments of the function. |
|
@titovmaxim |
|
Yesterday, I experimented with an alternative approach to handling the exists check on Android. Instead of attempting to open the file and falling back to listing the directory, it reads the manifest from the apk and caches the paths. This has had quite promising results so far. |
|
Interesting approach. |
|
Leaving aside the generic Will you accept a PR if I try it? Any preference on Side note: the exist check for i18n also causes problems for iOS: #2345, so I'm doubly motivated. |
|
Just remove the existence check in I18NBundle and call it a day. I am opposed to adding an |
|
ok adding the workaround in I18NBundle right now. |
The project has two simple translation files: one base (bundle.properties) and one for the language of choose (bundle_ru.properties). So the chain is very short - just two files. The files are simple and small (about 5 Kb).
I18NBundle.createBundle works ok on Desktop. However on Android in takes unreasonable time to load. On Galaxy S III it takes 0.8 sec. Apparently there is some bug or a problem. Could be related to very-very slow check is a directory exists on android internal files.
This make I18NBundle close to unusable on Android. Changing from I18NBundle to simple json load of two similar files solves the problem in no time.