日期:2014-05-16  浏览次数:21275 次

RandomAccessFile 类读写测试及其性能优化(一)
package io;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * RandomAccessFile 类读写测试及其性能优化(一)
 * 
 * GenerateIntArray生成count个数组,每个数组里面有size个整数,然后将生成的数据写入文件.
 * 整数通过Random.nextInt(total)来生成.
 * 初始化时,数组数据都是0,调用refreshDataArr()可生成新数据填充数组
 * 
 * 生成数据的方法有:
 * (1) refreshDataArr() 使用双重循环生成数据.
 * (2) refreshDataArr_M() 使用count个线程,每个线程中生成size个数据
 * 
 * 将数据写入文件的方法有:
 * (1)writeData2File(File f) 
 *    循环调用RandomAccessFile.writeInt(int)方法,每个数据都写一次,一共写了count*size次
 * (2)writeData2File_B(File f) 
 *    该方法先将coutn个整数转换成字符数组,并将count个字节数组按顺序组合到一个大的字节数组中
 *    然后调用RandomAccessFile.write(byte[] byteArr);方法一次性写入size个整数.
 * (3)writeData2File_M(File f)
 *    该方法启动count个线程,每个线程使用writeData2File_B中的方法,一次性写入size个整数
 * 
 * 由下面的测试结果可知,通过RandomAccessFile.write(byte[] byteArr)写入字节数组的方式一次性写入
 * size个整数时写入速度最快,比一次写入一个整数快了很多.多线程写入时性能提升不大,只有在count不大,但是
 * size巨大时多线程方法写入有一些提升,因为生成count个线程并且要进行线程调度也需要消耗一些系统资源.
 * 
 * 多线程方式生成数据,也只有在size特别大(100000),count不是很大时有速度提升.
 * 
 * RandomAccessFile进行多线程写似乎并不能提升速度,其中原因有待研究.
 * 
 * 数据量非常小时,使用单线程一次生成一个数据,以及一次写入一个整数时速度快
 * (因为使用写字节数组方式一次性写入size个整数时需要将整数转换成字节数组,这有一定的开销).
 * 
 * 下面是部分测试数据(耗时单位是 耗时(纳秒)/100000)
 * 
 * 
count = 10, size = 10 

正在生成数据,请稍后...
refreshDataArr 生成数据成功, 耗时:0

正在生成数据,请稍后...
refreshDataArr_M 生成数据成功, 耗时:96

正在写入数据,请稍后...
数据已写入文件D:\D\test_data.dat\test_data.dat
writeData2File_B写入数据耗时:16

正在写入数据,请稍后...
数据已写入文件D:\D\test_data.dat\test_data.dat
writeData2File 写入数据耗时:12

正在写入数据,请稍后...
数据已写入文件D:\D\test_data.dat\test_data.dat
writeData2File_M写入数据耗时:39

----------------------------------------------------------------
count = 100, size = 1000 

正在生成数据,请稍后...
refreshDataArr 生成数据成功, 耗时:123

正在生成数据,请稍后...
refreshDataArr_M 生成数据成功, 耗时:303

正在写入数据,请稍后...
数据已写入文件D:\D\test_data.dat\test_data.dat
writeData2File_B写入数据耗时:246

正在写入数据,请稍后...
数据已写入文件D:\D\test_data.dat\test_data.dat
writeData2File 写入数据耗时:6623

正在写入数据,请稍后...
数据已写入文件D:\D\test_data.dat\test_data.dat
writeData2File_M写入数据耗时:308

----------------------------------------------
count = 100, size = 10000 

正在生成数据,请稍后...
refreshDataArr 生成数据成功, 耗时:894

正在生成数据,请稍后...
refreshDataArr_M 生成数据成功, 耗时:1645

正在写入数据,请稍后...
数据已写入文件D:\D\test_data.dat\test_data.dat
writeData2File_B写入数据耗时:753

正在写入数据,请稍后...
数据已写入文件D:\D\test_data.dat\test_data.dat
writeData2File 写入数据耗时:70863

正在写入数据,请稍后...
数据已写入文件D:\D\test_data.dat\test_data.dat
writeData2File_M写入数据耗时:1605
------------------------------------
count = 1000, size = 10000 

正在生成数据,请稍后...
refreshDataArr 生成数据成功, 耗时:9078

正在生成数据,请稍后...
refreshDataArr_M 生成数据成功, 耗时:15067

正在写入数据,请稍后...
数据已写入文件D:\D\test_data.dat\test_data.dat
writeData2File_B写入数据耗时:25753

正在写入数据,请稍后...
数据已写入文件D:\D\test_data.dat\test_data.dat
writeData2File 写入数据耗时:701698

正在写入数据,请稍后...
数据已写入文件D:\D\test_data.dat\test_data.dat
writeData2File_M写入数据耗时:13727
----------------------------------------------
count = 1000, size = 100000 

正在生成数据,请稍后...
refreshDataArr 生成数据成功, 耗时:86459

正在生成数据,请稍后...
refreshDataArr_M 生成数据成功, 耗时:82820

正在写入数据,请稍后...
数据已写入文件D:\D\test_data.dat\test_data.dat
writeData2File_B写入数据耗时:345980

正在写入数据,请稍后...
数据已写入文件D:\D\test_data.dat\test_data.dat
writeData2File 写入数据耗时:0(耗时太长,这里放弃测试)

正在写入数据,请稍后...
数据已写入文件D:\D\test_data.dat\test_data.dat
writeData2File_M写入数据耗时:273550
 *
 */
public class GenerateIntArray
{
  private int     count   = 1000;             // 数组的个数,
  private int     size    = 10;               // 每个数组的元素个数
  private int[][] dataArr;
  private Random  random  = new Random(1000);

  public GenerateIntArray()
  {
    dataArr = new int[count][size];
  }

  public GenerateIntArray(int count, int size)
  {
    this.count = count;
    this.size = size;
    this.dataArr = new int[count][size];
  }

  public int[][] getDataArr()
  {
    return