私は現在、Apache Derby データベースを使用していくつかのユースケース (挿入、更新、削除など) を評価するための Java ベンチマークを開発しています。
私の実装は次のとおりです。
JVM をウォームアップした後、一連の (for ループ: (100k から 1M の反復)) をÌNSERT
データベースの (現時点では単一のテーブル) で実行します。Apache Derbyなので、知っている人のために、すべてのモードをテストします(メモリ内/組み込み、メモリ内/ネットワーク、永続的/組み込み、永続的/ネットワーク)
プロセスの実行は、singleThreaded または multiThreaded (使用してExecutors.newFixedThreadPool(poolSize)
さて、ここに私の問題があります:
1 つのスレッドのみでベンチマークを実行すると、かなり現実的な結果が得られます
In memory/embedded[Simple Integer Insert] : 35K inserts/second (1 thread)
次に、1 つ、次に 2 つの (同時) スレッドを順番に実行することにしました。
今、私は次の結果を持っています:
In memory/embedded[Simple Integer Insert] : 21K inserts/second (1 thread)
In memory/embedded[Simple Integer Insert] : 20K inserts/second (2 thread)
1 スレッドの結果が大きく変わるのはなぜですか?
基本的に、ループの前後にタイマーを開始および終了します。
// Processing
long start = System.nanoTime();
for (int i = 0; i < loopSize; i++) {
process();
}
// end timer
long absTime = System.nanoTime() - start;
double absTimeMilli = absTime * 1e-6;
そして process() メソッド:
private void process() throws SQLException {
PreparedStatement ps = clientConn.prepareStatement(query);
ps.setObject(1, val);
ps.execute();
clientConn.commit();
ps.close();
}
実行は順次処理されるため、コードの残りの部分 (データ処理) によってベンチマークが変更されるべきではありませんか?
シーケンシャル スレッドの数が増える (たとえば、1、2、4、8) と、結果は悪化します。
これが混乱を招く場合は、事前に申し訳ありません。必要に応じて、さらに情報を提供したり、再度説明したりします。
助けてくれてありがとう:)
編集 :
上記の実行を呼び出すメソッド (Usecase クラスから) は次のとおりです。
@Override
public ArrayList<ContextBean> bench(int loopSize, int poolSize) throws InterruptedException, ExecutionException {
Future<ContextBean> t = null;
ArrayList<ContextBean> cbl = new ArrayList<ContextBean>();
try {
ExecutorService es = Executors.newFixedThreadPool(poolSize);
for (int i = 0; i < poolSize; i++) {
BenchExecutor be = new BenchExecutor(eds, insertStatement, loopSize, poolSize, "test-varchar");
t = es.submit(be);
cbl.add(t.get());
}
es.shutdown();
es.awaitTermination(Long.MAX_VALUE,TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return cbl;
}