Static data structures on embedded devices (specifically Android)
I started working on some Android applications and asked a question about how people usually deal with situations where you have a static dataset and there is an application where this data is needed in memory as one of the standard Java collections or as an array.
In my current specific problem, I have a spreadsheet with some pre-calculated data. It consists of ~ 100 rows and 3 columns. 1 column is a row, 1 column is a float, 1 column is an integer. I need to access this data as an array in java.
It seems I could:
1) Encode to XML - This would be an intensive process to decode in my experience.
2) embed in SQLite database - there seems to be a lot of overhead for static data access. I only need access to the array in ram.
3) Build into binary blob and read. (never did this in java, i missed void *)
4) Create a python script to take a CSV version of my data and spit out a java function that adds values to my desired structure with hardcoded values.
5) Store an array of strings through the androids resource engine and calculate the remaining 2 columns when loading the app. In my case, the computation would require a lot of calls to Math.log, Math.pow and Math.floor, which I would rather not do for load times and battery usage.
I mainly work in low power applications in C and so my # 4 is what I used in these situations.
It seems much easier to access static data structures in java / android.
Maybe I just feel overuse of the battery, and in my only case, I imagine the answer is that it doesn't really matter, but if every app were in that position it might start to matter.
What approaches do people usually take in this situation? What did I miss?
a source to share
I would do modified # 5:
strings.xml
<string-array name="some_data">
<item>string|0.56|100</item>
</string-array>
Parser.java
String[] arr = getResources().getStringArray(R.array.some_data);
for (String str : arr) {
string[] columns = str.split("|");
// to Java objects or parallel arrays
}
Microbenchmark:
<string-array name="data">
<item>some0|10|1.0</item>
...
<item>some99|199|1.99</item>
</string-array>
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
long start = System.currentTimeMillis();
String[] arr = getResources().getStringArray(R.array.data);
ArrayList<Triple> triples = new ArrayList<Triple>();
for (String s : arr) {
String[] parts = s.split("\\|");
Triple tr = new Triple();
tr.str = parts[0];
tr.i = Integer.valueOf(parts[1]);
tr.f = Float.valueOf(parts[2]);
triples.add(tr);
}
System.out.println(System.currentTimeMillis() - start);
return true;
}
static class Triple {
public String str;
public int i;
public float f;
}
05-02 21:17:50.418: INFO/System.out(609): 125
05-02 21:17:51.128: INFO/System.out(609): 124
05-02 21:17:52.368: INFO/System.out(609): 124
05-02 21:17:53.158: INFO/System.out(609): 127
05-02 21:17:53.858: INFO/System.out(609): 123
05-02 21:17:54.688: INFO/System.out(609): 124
05-02 21:17:55.778: DEBUG/dalvikvm(609): GC freed 14380 objects / 525008 bytes in 136ms
At 1.6 ADP1 .
a source to share
For (3) you can use ObjectInputStream created from FileInputStream (see class level Javadoc for some copy + paste code) to deserialize objects from binary data stored in file.
To create a binary file, use ObjectOutputStream and similarly FileOutputStream.
a source to share