codenameone

How can Writer Speed be Enhanced


The following reads bytes in a file and writes these bytes as characters in another file using Writer. I have extracted it from this discussion

        String filePath = Display.getInstance().getDatabasePath("TestDB.db");
        FileSystemStorage fss = FileSystemStorage.getInstance();
        InputStream is = fss.openInputStream(filePath);
        byte[] plainBytes = Util.readInputStream(is);

        //encrypt database file content

        Log.p("Starting file encryption...");

        byte[] cipherByteArray = FilesCipher.encryptFile(plainBytes);

        Log.p("Done encrypting file");

        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(cipherByteArray);

        String encryptedFilePath = fss.getAppHomePath() + "EncryptedDB.db";

        Log.p("Writing to new a file started..."); 

        try (Writer w = new OutputStreamWriter(fss.openOutputStream(encryptedFilePath), "ISO-8859-1")) {
            int nextChar = byteArrayInputStream.read();
            while (nextChar > -1) {
                char[] charArray = {(char) nextChar};
                w.write(charArray);
                nextChar = byteArrayInputStream.read();
            }

            Log.p("Done writing to a new file");

        } catch (Exception e) {
            Log.p("Error " + e);
        }

If file size of the file being read (Eg TestDB.db) is small (less than 500KB), In Simulator & Device, the Writer writes to the new file (Eg. EncryptedDB.db) very fast.

If the file is large eg. 3MB, In Simulator it's written very fast to the new file. But in a device it takes more than 2 minutes. I tested in Android 10.

I have confirmed that encryption is very fast since even when file is large, Log.p("Writing to new a file started..."); is executed within 2 Seconds even in the device.

When file is large, in a Simulator Log.p("Done writing to a new file"); is executed within seconds but in a device it takes more than 3 minutes. This means Writer is slow in a device.

Writer doesn't have a function to write bytes directly.

How can Writer speed be enhanced in devices?


Solution

  • Writing/reading a single character has always been slow. You need to use a buffer and read with power of two multiples (our default is 8192 if I recall correctly).

    You're allocating a single character array 3M times on a device... The fact that it runs reasonably well on a desktop is amazing.

    I think the writing is the most important part here:

    // before the loop
    char[] charArray = new char[cipherByteArray.length];
    int size = 0;
    
    int nextChar = byteArrayInputStream.read();
    // in the loop code...
    while (nextChar > -1) {
         charArray[size] = (char)nextChar;
         size++;
         if(size == charArray.length) {
             w.write(charArray);
             size = 0;
         }
         nextChar = byteArrayInputStream.read();
    }
    
    
    // then after the loop is complete...
    if(size > 0) {
        w.write(charArray, 0, size);
    }
    

    This absolutely enhances Writer speed. A file of size 11.9MB (It has images stored as blob), results to the following log in Android Studio. Encryption completes in 3 sec & writes to the new file in 1 sec

    2024-07-28 11:03:08.375 28314-28444 {App Name}        D  [EDT] 0:0:42,937 - Starting file encryption...
    2024-07-28 11:03:08.416 28314-28330 {App ID}          I  Background young concurrent copying GC freed 10(31KB) AllocSpace objects, 1(8196KB) LOS objects, 0% free, 43MB/43MB, paused 131us total 112.118ms
    2024-07-28 11:03:09.839 28314-28330 {App ID}          I  Background concurrent copying GC freed 1947(87KB) AllocSpace objects, 3(21MB) LOS objects, 36% free, 41MB/65MB, paused 133us total 117.032ms
    2024-07-28 11:03:11.031 28314-28444 {App Name}        D  [EDT] 0:0:45,594 - File encryption DONE
    2024-07-28 11:03:11.034 28314-28444 {App Name}        D  [EDT] 0:0:45,597 - Saving encrypted file...
    2024-07-28 11:03:11.177 28314-28330 {App ID}          I  Background concurrent copying GC freed 18(24KB) AllocSpace objects, 3(28MB) LOS objects, 33% free, 47MB/71MB, paused 231us total 104.218ms
    2024-07-28 11:03:12.454 28314-28444 {App Name}        D  [EDT] 0:0:47,17 - DONE Saving encrypted file