0

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);
    }
NoBugs
  • 9,310
  • 13
  • 80
  • 146

2 Answers2

2

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • That increases write speed significantly - 0.13 MB/s internal. I forgot about that, it's been awhile since I did that in Java. Come to think of it, I remember copying many small files was incredibly slow on desktop too for some reason, so maybe this benchmark is accurate for this case? – NoBugs May 25 '14 at 07:39
0

You're introducing a ton of overhead here:

        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

You're closing and opening the file every 4k (1024 times per file). Instead you should open it just once outside the loop.

This is still far from being a scientific test. You're making a bunch of API calls that aren't going to show the real speed of the device. Also, you might have a bunch of filesystem re-sizing overhead going on.

A better method might be:

  • Open the file
  • Write the desired size of data
  • Seek to the beginning of the file
  • Flush
  • Start timer
  • Write desired size of data in as big of a chunk as possible
  • Stop timer
  • Cleanup
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328