Java および C# 用の 32 コア サーバーで同じ関数を実行する多くのスレッドの生成をテストしています。スレッドプールを使用して、1、2、4、8、16、または 32 個のスレッドにわたってバッチ処理される関数の 1000 回の反復でアプリケーションを実行します。
1、2、4、8、および 16 の同時スレッドで、Java は少なくとも C# の 2 倍高速です。ただし、スレッド数が増えるとギャップが縮まり、32 スレッドまでに C# の平均実行時間はほぼ同じになりますが、Java は 2000 ミリ秒かかることがあります (一方、両方の言語は通常約 400 ミリ秒実行されます)。Java は、スレッドの反復ごとにかかる時間の大幅なスパイクにより、悪化し始めています。
編集これはWindows Server 2008です
EDIT2 以下のコードを変更して、Executor Service スレッドプールの使用を示すようにしました。Java 7もインストールしました。
ホットスポット VM で次の最適化を設定しました。
-XX:+UseConcMarkSweepGC -Xmx 6000
しかし、それはまだ物事を改善していません。コードの唯一の違いは、以下のスレッドプールを使用していることと、使用する C# バージョンであることです。
http://www.codeproject.com/Articles/7933/Smart-Thread-Pool
Java をより最適化する方法はありますか? パフォーマンスが大幅に低下している理由を説明できますか?
より効率的な Java スレッドプールはありますか?
(テスト関数を変更するという意味ではないことに注意してください)
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class PoolDemo {
static long FastestMemory = 2000000;
static long SlowestMemory = 0;
static long TotalTime;
static int[] FileArray;
static DataOutputStream outs;
static FileOutputStream fout;
static Byte myByte = 0;
public static void main(String[] args) throws InterruptedException, FileNotFoundException {
int Iterations = Integer.parseInt(args[0]);
int ThreadSize = Integer.parseInt(args[1]);
FileArray = new int[Iterations];
fout = new FileOutputStream("server_testing.csv");
// fixed pool, unlimited queue
ExecutorService service = Executors.newFixedThreadPool(ThreadSize);
ThreadPoolExecutor executor = (ThreadPoolExecutor) service;
for(int i = 0; i<Iterations; i++) {
Task t = new Task(i);
executor.execute(t);
}
for(int j=0; j<FileArray.length; j++){
new PrintStream(fout).println(FileArray[j] + ",");
}
}
private static class Task implements Runnable {
private int ID;
public Task(int index) {
this.ID = index;
}
public void run() {
long Start = System.currentTimeMillis();
int Size1 = 100000;
int Size2 = 2 * Size1;
int Size3 = Size1;
byte[] list1 = new byte[Size1];
byte[] list2 = new byte[Size2];
byte[] list3 = new byte[Size3];
for(int i=0; i<Size1; i++){
list1[i] = myByte;
}
for (int i = 0; i < Size2; i=i+2)
{
list2[i] = myByte;
}
for (int i = 0; i < Size3; i++)
{
byte temp = list1[i];
byte temp2 = list2[i];
list3[i] = temp;
list2[i] = temp;
list1[i] = temp2;
}
long Finish = System.currentTimeMillis();
long Duration = Finish - Start;
TotalTime += Duration;
FileArray[this.ID] = (int)Duration;
System.out.println("Individual Time " + this.ID + " \t: " + (Duration) + " ms");
if(Duration < FastestMemory){
FastestMemory = Duration;
}
if (Duration > SlowestMemory)
{
SlowestMemory = Duration;
}
}
}
}