03-20-2012 07:40 AM
Using the BB 9860 Torch. I am experiencing very slow read times.
Ive written a little test app to see the load times:
now the problem is that I call readStream.read(ReadBuffer,0,65536); alot.
Each time this takes 12 milliseconds! My program takes over 30 seconds to load. And this is suppose to be fast map scrolling :/
the size read makes no real difference. Just the initalisation of reading.
new stream: 2
new array: 0
Read 1024: 12
InputStream readStream =FileBuff.openInputStream();
03-21-2012 03:15 PM
Can you please post some more details on what are you trying to do?
You are saying that reading a file takes about 12 MS but your application takes more than 30 seconds to load.
If these are the correct numbers, I think that there might be an issue someplace else. Try using the profiler and see where most of your loading time is spent.
03-22-2012 05:34 AM
Ive profiled it. And all I get back is some class.forName() function taking up 80% of my load time.
No idea what that is.
But my app is a map base app. It reads from shape files and draws vector graphics onto the screen. As well as reading from dbf files for info on the shapes.
These files are located on the SDcard. The amount of reads that goes on is quite high. (there are 52 files and numerous amounts of reads carried out on each file).
Now the Android runs this perfectly fast. Less than a second. Yet my app takes 30 seconds. I have brought the time down by about half by placing the files onto the //Store instead. (internal memory). But this isnt an ideal situation and 15 seconds is still not feasible.
If you have any idea as to how to fix it, I would be very greatful as 6 weeks of work on the emulator has now gone down the drain due to slow device. Ive commented out all sorts of section, writen a test app etc. and im pretty confident that reading is the problem. (I timed the read command).
int Start = System.currentTimeMillis();
String end = String.valueOf( System.currentTimeMillis() - Start);
add(new LabelField("Read : " + end));
in total connector-read-close. Can take up to 30ms where as Android is 2ms. (In my app I keep the file open and read everything I need before closing). So there is something going wrong.
I had a theory, but Its probably not correct, that each time it reads it has to check the key signing? which is slowing it down. Probably not true at all.
Can you please shed light on whats going on and how to fix it. Again, much appreciated!
03-22-2012 10:02 AM
I can try and give you some suggestions:
1. First of all, the read function does not read the all file. You should use it with a loop to read the all input stream.
2. Try and use the IOUtilities.streamToBytes function. It will read the complete stream and since it a built in function, it might be a bit faster.
3. If you have to read multiple files, consider using threads to read simultaneity.
4. Try and merge files. This will reudce the time of opening another file.
5. Consider using the persistent storage or SQLite to keep your data as they might give you better performance.
6. Make sure you don't read your files on the UI thread.
7. Check out the OpenRawInputStream in ExtendedFileConnection class. it does not do automatic decryption so it might improve the app performance.
Hope that helps,
03-22-2012 10:13 AM
Hey, thanks for your response,
I dont want to read the entire files as some are over 100MB. I use read and seekable to allow me to set position in the file. (Ive tested with very small files but still loads slow).
Using streamToBytes causes memory overflow. Due to file size.
Opening a file is not so much a problem as reading, as I can keep it open for the entire draw of map, and close at end.
I have done tests on reading from my sqlite DB and its even slower. D:
Number 6 stands out though. Can you elaberate on reasoning why not to. And how to go about this? The only think I can think of is calling a new thread to read it, but waiting till the thread has completed loading file, before you continue the UI thread. This to me seems to defeat the whole point.
Ill give the openRawInputStream a try, thanks.
03-22-2012 10:39 AM
The application UI runs on the main thread.
So every action you take on that thread slows it down or even causing it to hang.
This is very important when while networking and opening connection since these are blocking operations and your UI won't be able to do anything as long as these operations are running.
If you must run such operation before displaying the UI, there are couple of things you can/should do:
1. Add a splash screen to your application. This is a very (if not the most) common solution. You add an initial screen which present some text, image and a progress bar and display it for a few seconds. This is a good solution since in the mean while you do all your work in the background and the user is displayed with a nice screen (solve the application hangs problem). Also, the splash screen is very helpful as it a good place to put ads, instructions, etc'.
2. Display the UI gradually. Just like browsers, first the text is displayed and the images are loaded on the background. Once loaded, update the UI with the images.
03-22-2012 10:56 AM - edited 03-22-2012 10:58 AM
While these are great suggestions, they are not practical in my situation unfortuantely.
As a map app, it requires scrolling around alot. (panning). And each time requires a new image draw. Hence file reading.
So loading in the background while the user uses my login screen would work to some extent, but only that one instance. Once they move the map, they are in a world of pain.
And again with the UI display gradually. The map is made up of files that work in Layers. But the final load time would still exist. I had at one point written code just to draw the part of the map that is not known, but keep the existing map where possible. The Android draws the entire thing in fractions of a second. I put it down to a JavaME/Blackberry thing. Where rapid constant file reading is just not feasible.
Im currently considering using the mapfield. If its possible to replace the map fetching part of this with my own webservice that would be great! I cant get this **bleep** SOAP implementation to work though. (using javaME SDK) to generate stubs. Wont accept byte. How else I should represent an image I dont know.
Im sure I can figure that bit out, but how to integrate the use of the already existing mapfield would be great. So BBMaps.. but with my maps, and extra layers on top of it.
Edit: rawinputstream had no effect.