This is a bit of a frustration vent about the limitations of the platform, and the
difficulty of straying too far outside the envelope that codename1 has in mind
to support. The overall task is to add a dictionary with definitions to my
app. The raw form of the dictionary is 15 megabytes. Compressed about
5 megabytes. The natural representation as strings would therefore be in
the range of 30 megabytes in memory (assuming utf-16 is the underlying
representation of strings). This seemed a bit large, so I schemed to
store the bulk in compressed form in memory, so the data flow would
be <compresed file> -> <many short strings> -> <many short compressed strings>
Now for the surprise. The piece of code that compresses short strings
runs 1000 x slower on real android hardware than it does on my desktop.
public static byte[] zip(final String str) {
if ((str == null) || (str.length() == 0)) {
throw new IllegalArgumentException("Cannot zip null or empty string");
}
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream)) {
gzipOutputStream.write(str.getBytes(StandardCharsets.UTF_8));
}
byteArrayOutputStream.close();
return byteArrayOutputStream.toByteArray();
} catch(IOException e) {
throw new RuntimeException("Failed to zip content", e);
}
}
I haven't determined yet where the 3 order of magnitude loss of efficiency is.
Oh well, so much for elegance - what if I just skip the compression and store
the strings in native form? Surprise #2 is that without the compression, the
app just crashes without any notice of an "out of memory" condition, though
I'm pretty sure that's what happens.