IO slow on Android?

This should show the internal and external memory speeds, but unfortunately it says it's 0.02 or 0.04 MB/s? Is this an enormous inefficiency in Android, or coding error?

findViewById(R.id.buttonStorageSpeed).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                double SDSpeed = MBPSTest(getExternalCacheDir()); // /sdcard
                double MemSpeed = MBPSTest(getCacheDir());        // /data/data
                final AlertDialog dialog = new AlertDialog.Builder(thisContext)
                .setTitle("Memory speed")
                .setMessage( "Internal:"+String.valueOf(MemSpeed) + "\n"  + "SD:"+String.valueOf(SDSpeed))
                .create();
                dialog.show();
            }
        });




/**
     * Test MB/s write speed in some directory.
     * Writes 4MB, deletes it after.
     * @param outdir
     * @return
     */
    private double MBPSTest(File outDir) {

        long start = System.currentTimeMillis();
        try {
            for (int fnum = 0; fnum < 1024; fnum++) {
                File out = new File(outDir,"TESTspeed"+String.valueOf(fnum));
                FileOutputStream fos = new FileOutputStream(out);

                //Write 4k files
                for (int i=0; i < 1024; i++) {
                    fos.write(65);//A
                    fos.write(69);//E
                    fos.write(73);//I
                    fos.write(79);//O
                }
                fos.flush();
                fos.close();
                //System.out.println("Wrote file.");
            }
            //Wrote 4MB

            //Toast.makeText(getApplicationContext(), "Wrote External at: "+String.valueOf(4.0 / (elapsed/1000.0) )+" MB/S", Toast.LENGTH_LONG).show();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return 0;
        } catch (IOException e) {
            e.printStackTrace();
            return 0;
        }

        long elapsed = System.currentTimeMillis() - start;

        //Clean up:
        for (int fnum = 0; fnum < 1024; fnum++) {
            File out = new File(outDir, "TESTspeed"+String.valueOf(fnum));
            out.delete();
        }
        // 4 MB / (seconds)
        return 4.0 / (elapsed/1000.0);
    }
Jon Skeet
people
quotationmark

As well as the overhead Jonathon mentioned of opening and closing the file a lot, you're also calling write(int) for every single byte.

Either use write(byte[]) with a big buffer, or use a BufferedOutputStream to wrap the FileOutputStream. There may be some buffering in FileOutputStream already, but equally there may not be. You may well find that once you've got fewer write operations (but still the same amount of data) it's much faster.

people

See more on this question at Stackoverflow