日常的にコードを書く人ではない、趣味の園芸な自分が読んでも楽しめる。
一通り読んだものの咀嚼出来ていないところがあるので、時間を見つけて査読したいな。
ちょっと前に、Junitのソースコードを眺めていたんだけど、この本読んでる最中に、
「ああ、ここの記述はあそこのソースでもやってたなぁ」と思いだした。
もう一度、Junitちゃんと読んでみようかなぁ。
コレクションAPIのパフォーマンス比較をするために、測定用フレームワークを作っていて付録Aで
そのコードを公開している、コード自体はとても小さいシンプルなものだけど、本書の中のパターン
が使われている。
後でWebで見たかったので写経してみた。
コメントいれてる。変なところがあったら御免なさい。
このListSerchクラスのserchメソッドの実行時間を計測すると
search 25.30 77.81 551.10 と結果出力される。
要素数が増加すると実行時間が増えている。
- import java.util.ArrayList;
- import java.util.List;
- public class ListSerch {
- private List<Integer> numbers;
- private int probe;
- public ListSerch(int size){
- numbers = new ArrayList<Integer>();
- for (int i = 0; i < size; i++) {
- numbers.add(i);
- probe = size / 2;
- }
- }
- //ArrayListの真ん中を取得させる。
- public void search(){
- numbers.contains(probe);
- }
- }
ドライバークラスは以下。
テストしたいクラスに含まれるメソッドの配列を引数にしてMethodsTimerインスタンス化。
report()メソッドを実行する。
結果はコンソールに
メソッド名 1回実行での時間 10回実行での合計時間 100回実行での合計時間 ・・・合計が1秒こえるまでやる。
- public class TestDriver {
- public static void main(String[] args) throws Exception{
- MethodsTimer tester = new MethodsTimer(ListSerch.class.getDeclaredMethods());
- tester.report();
- }
- }
- import java.lang.reflect.Method;
- public class MethodsTimer {
- public final Method[] methods;
- private static final int MAXIMUM_SIZE = 100;
- public static final int ONE_SECOND = 1000000000;
- public MethodsTimer(Method[] methods){
- this.methods = methods;
- }
- public void report() throws Exception{
- for(Method each : methods){
- System.out.print(String.format("%.2f\t", r.getMethodTime()));
- for (int size = 1; size <= MAXIMUM_SIZE; size *=10)
- {
- MethodTimer r = new MethodTimer(size, each);
- r.run();
- System.out.print(r.getMethodTime() + "\t");
- }
- System.out.println();
- }
- }
- }
- import java.lang.reflect.Constructor;
- import java.lang.reflect.Method;
- public class MethodTimer {
- private final int size;
- private final Method method;
- private Object instance;
- private long totalTime;
- private int iterations;
- private long overhead;
- public MethodTimer(int size, Method method) throws Exception{
- this.size=size;
- this.method=method;
- instance = createInstance();
- }
- public MethodTimer(int iterations) throws Exception{
- this(0,MethodTimer.Overhead.class.getMethod("nothing", new Class[0]));
- this.iterations = iterations;
- }
- private static MethodTimer overheadTimer(int iterations) throws Exception{
- return new MethodTimer(iterations);
- }
- private Object createInstance() throws Exception {
- Constructor<?> constructor = method.getDeclaringClass().getConstructor(
- new Class[] { int.class });
- return constructor.newInstance(new Object[] { size });
- }
- double getMethodTime(){
- return (double)(totalTime - overhead) / (double)iterations;
- }
- void run() throws Exception {
- iterations = 1;
- while (true) {
- totalTime = computeTotalTime();
- if (totalTime > MethodsTimer.ONE_SECOND)
- break;
- iterations *= 2;
- }
- overhead = overheadTimer(iterations).computeTotalTime();
- }
- private long computeTotalTime() throws Exception {
- long start = System.nanoTime();
- for (int i = 0; i < iterations; i++) {
- method.invoke(instance, new Object[0]);
- }
- return System.nanoTime() - start;
- }
- public static class Overhead {
- public Overhead(int size) { }
- public void nothing() { }
- }
- }