JDK 6.0
昔、ASCIIの実践Javaで、artonさんがStreamとNIOでファイルコピーの比較を掲載していたのだけど、あの頃は1.4だったので6.0ならば、どうかなと思って、やってみた。環境は、Core 2 Duo(3.4Gにover clock)で、Windows XP、DiskはSATA(3Gbps) Seagateの7200rpmのもの。ローカルファイル(サイズ670MB)のコピー時間を計ってみた。3回測定し、平均値から大きく逸脱しているものは除いて平均をとってみた。単位は秒。
Stream:
| 1k | 2k | 4k | 8k | 16k | 32k | 64k |
|---|---|---|---|---|---|---|
| 26.1 | 26.0 | 26.2 | 26.0 | 26.3 | 28.7 | 28.4 |
Nio:
| 1k | 2k | 4k | 8k | 16k | 32k | 64k |
|---|---|---|---|---|---|---|
| 26.4 | 26.1 | 26.3 | 24.8 | 26.3 | 26.3 | 28.0 |
う〜ん、今回もNIOとStreamでは大差無しかな。というかバッファサイズって1kもあれば十分なんだね。でもディスクアクセスの音を聞いていると、どうもバッファサイズは効いていないような気もする。もっとOSに近いレイヤでバッファリングがかかっていて、アプリケーションでバッファリングしても、これだけCPUが速い時代になると無意味なのかもしれない。何しろCPU使用率は、どのケースも有意差無しだったし。しかしバッファサイズが大きいとなんで遅くなるんだろう。Streamが32kで、ちょっと遅くなるのに対しNioは64kからちょっと遅くなるという傾向も興味深い。
ちなみにcmdでふつーにcopyしたら、27.8秒だった。cmdのcopyもバッファサイズが大きいのかな。
使用したプログラム:
--- CopyByStream.java ---
import java.io.*;
public class CopyByStream {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
String copyFrom = args[0];
String copyTo = args[1];
int bufferSize = 32 * 1024;
if (args.length > 2) {
bufferSize = Integer.parseInt(args[2]) * 1024;
}
if (bufferSize <= 0)
throw new IllegalArgumentException("Invalid buffer size(=" + bufferSize + ").");
byte[] buf = new byte[bufferSize];
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(copyFrom);
out = new FileOutputStream(copyTo);
while (true) {
int readLength = in.read(buf);
if (readLength == -1) break;
out.write(buf, 0, readLength);
}
}
catch (IOException ex) {
ex.printStackTrace();
}
finally {
if (in != null) {
try {in.close();}
catch (IOException ex) {ex.printStackTrace();}
}
if (out != null) {
try {out.close();}
catch (IOException ex) {ex.printStackTrace();}
}
System.console().printf("Elapsed %,d%n",System.currentTimeMillis() - startTime);
}
}
}
--- CopyByNio.java ---
import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.ByteBuffer;
public class CopyByNio {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
String copyFrom = args[0];
String copyTo = args[1];
int bufferSize = 32 * 1024;
if (args.length > 2) {
bufferSize = Integer.parseInt(args[2]) * 1024;
}
if (bufferSize <= 0)
throw new IllegalArgumentException("Invalid buffer size(=" + bufferSize + ").");
FileChannel in = null;
FileChannel out = null;
try {
in = new FileInputStream(copyFrom).getChannel();
out = new FileOutputStream(copyTo).getChannel();
ByteBuffer buf = ByteBuffer.allocateDirect(bufferSize);
while (true) {
int readLength = in.read(buf);
if (readLength == -1) break;
buf.flip();
out.write(buf);
buf.rewind();
}
}
catch (IOException ex) {
ex.printStackTrace();
}
finally {
if (in != null) {
try {in.close();}
catch (IOException ex) {ex.printStackTrace();}
}
if (out != null) {
try {out.close();}
catch (IOException ex) {ex.printStackTrace();}
}
System.console().printf("Elapsed %,d%n",System.currentTimeMillis() - startTime);
}
}
}
チャーリーくん家
チャーリーくんの家に遊びに行ってきた。チャーリーくんは夢久の兄弟。兄弟だけあって、仕草や容姿がとても似ている。


このまぶしそうな顔なんか、そっくり。




これは、お友達のNeneちゃん。なんかずっと怒っていたんだけど、なんで、そんなに怒っているのかは、良く分からず ^^;







どうも、私は、普段のチャーリー君の席に座ってしまっていたようで、そのせいか、ちょっとご機嫌斜めだったかも。ごめんね。








