Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
New Developer
New Developer
wam
Posts: 2
Registered: ‎07-16-2008
My Device: Not Specified

PersistentObject commit too slow

So I try to save some data to the PersistentStore. The data structure I use is IntHashtable<int, Vector<Object>>. The Hashtable has 1000 entries, each Vector has about 5 Strings inside.

Everything works as expected, but it takes 16s to commit the PersistentObject on a BlackBerry 8310, which is too long. While saving the data, the user interface is blocked and not usable! The code runs in a separated Thread and should not block.

I tried serializing the data to a String. This takes about 1s to save to the store.

Do you have any other tricks how to save data to the store?

Thanks,
wam

 

 

public static void write(final String key, final Object value) { Thread t = new Thread() { public void run() { PersistentObject store = PersistentStore.getPersistentObject(key.hashCode()); store.setContents(value); long stamp = System.currentTimeMillis(); store.commit(); long duration = System.currentTimeMillis() - stamp; log("commit " + key + " in " + duration + "ms"); } }; t.start(); }

 

Retired
mkirkup
Posts: 179
Registered: ‎07-14-2008
My Device: Not Specified

Re: PersistentObject commit too slow

As noted in the following memory best practices whitepaper, you should minimize the use of high level objects within your PersistentStore for optimal performance on the smartphone.  That said, it doesn't account for the delays that you are seeing in your implementation below. 

 

Here are a couple more suggestions:

 

1) You should never use key.hashCode() as the GUID for your PersistentStore.  There is a feature in the BlackBerry JDE and BlackBerry JDE Plugin for Eclipse that allows you to convert text to a long value.  As such, we would recommend you create a static final long ID variable in your application which represents the GUID based on your package and class name.  This would ensure that you do not have a collision with anyone else on the smartphone.

 

2) You should only ever call setContents() once.  This would occur on the very first time that you are adding data.  For each subsequent call you should be calling getContents() and then modifying that object directly.  By modifying the object directly, you would then call commit at the end of your work where the system would properly commit your changes.  In your current implementation you are forcing the VM to destroy the previous version of your IntHashtable and then replace it with the new one which causes garbage collection and unnecessary processing by the VM.  It is important to note that commit operations are cascading (eg. they impact every PersistentObject on the system not just your PersistentObject).

 

 

Mike Kirkup
Director, Developer Relations
Developer
richard_puckett
Posts: 191
Registered: ‎04-03-2008
My Device: Bold 9700

Re: PersistentObject commit too slow

If you want to convert a String to long programmatically here's my little routine for doing so.  FYI.

 

 

public static long stringToLong(String str) { long hashValLong = 0; SHA1Digest sha1Digest = new SHA1Digest(); sha1Digest.update(str.getBytes()); byte[] hashValBytes = sha1Digest.getDigest(); for(int i = 0; i < 8; i++) { hashValLong |= ((long)(hashValBytes[i]) & 0x0FF) << (8*i); } return hashValLong; }

 

 

 

Developer
jhfisher
Posts: 16
Registered: ‎07-14-2008
My Device: 8310

Re: PersistentObject commit too slow

[ Edited ]

mkirkup wrote:

There is a feature in the BlackBerry JDE and BlackBerry JDE Plugin for Eclipse that allows you to convert text to a long value.  As such, we would recommend you create a static final long ID variable in your application which represents the GUID based on your package and class name.  


and if you use Netbeans or standard Eclipse you can use this utility:
http://www.northcubed.com/site/?p=4

 

Message Edited by jhfisher on 07-16-2008 03:07 PM
New Developer
rosskevin
Posts: 9
Registered: ‎07-16-2008
My Device: Not Specified

Re: PersistentObject commit too slow

I'll weigh in here with a bit more moderate/incremental approach than Mike about high level objects in the persistent store.  The typical solution is to perform more work/coding around utilizing more primitive objects, but before you go that far, you may try some other quick approaches.

 

1. 1000 entries of Vectors may just be too much so you may want to 1000 string arrays if the data is not highly modified.

2. Have you experimented with Object Grouping?  We have seen a fairly significant performance boost using object grouping.  I have discussed this with Mike in passing and we never came to a conclusion as to the accuracy of that statement or the technical reason why.  If we had more time, we would look into it, but I can tell you that we are storing complex object graphs that are grouped at each entry (i.e. 1000 groups in your case) and we had no need to optimize further. 

3.  Trying the above is quick and easy.  If that fails, you need to follow the advice Mike gives to simplify your object graph.

 

One more thing, if you happen to be parsing before storing (which I assume you are) remember not to iteratively call new StringBuffer().  Instead call stringBuffer.setLength(0) otherwise you are hogging memory before you get to the persistence call and the GC needs to step in and run, possibly for a good amount of time.  Pay close attention to your strings when parsing, we have found huge gains in optimizing this type of code.

 

 

Kevin Ross | President | Metova
www.metova.com
New Developer
New Developer
wam
Posts: 2
Registered: ‎07-16-2008
My Device: Not Specified

Re: PersistentObject commit too slow

[ Edited ]

thanks for all the good ideas. but the main problem is that it is freezing the user interface while commiting to the persistent store. am i doing something wrong in my code or is this behaviour normal?

 

edit:

changed my data structure to IntHashtable<int, String[]> instead of using Vectors. now it takes about 10s to save the 1000 elements to the store.

 

edit2:

i converted my data structure to a string and write it to the store. this took about 1s, which is good. but parsing back the string to the data structure (with indexOf and substring) takes 10s, so there i have the problem again...

Message Edited by wam on 07-17-2008 03:03 AM
Message Edited by wam on 07-17-2008 05:43 AM
Retired
mkirkup
Posts: 179
Registered: ‎07-14-2008
My Device: Not Specified

Re: PersistentObject commit too slow

For some background, grouping objects (using the ObjectGroup class) allows you to condense a set of object handles into one object handle.  The major benefit to using this technique is that your application will consume less object handles since there are a finite number of object handles available across the entire system.

 

To comment on Kevin's experience below, grouping your object will automatically commit it so you are essentially just moving the time when your commit is occuring such that the final commit will take less time or appear faster.

 

 

Mike Kirkup
Director, Developer Relations
Retired
mkirkup
Posts: 179
Registered: ‎07-14-2008
My Device: Not Specified

Re: PersistentObject commit too slow

This is how I am assuming you have implemented your application at a high level:

 

1) Run application which connects to some service and downloads data to the device.

2) Download all of the data to the device and place in IntHashtable based on your data structure.

3) Create your PersistentStore and call setContents passing in the IntHashtable and commiting the changes.

 

The complaint being that you are seeing the UI freeze on the device during this commit operation.  If I got all of this right, here is my recommendation for how to improve the performance of your application.

 

1) Run your application and on initialization create the "shell" of your data structure and place in the PersistentStore using setContents.  Then start downloading the data.

2)  Augment this step such that as the data is being downloaded you are adding it to the existing data structure in your PersistentStore simply by modifying the IntHashtable itself.  Do not ever call setContents again.

 

Note:  You will want to find the optimal balance between the amount of data in each commit.  My best recommendation is either 4KB or 64KB depending on the amount of data 

 

3)As a final step, call commit which should be a fairly small operation (it may even be a no-op).  

 

 

Mike Kirkup
Director, Developer Relations