【发布时间】:2012-04-12 02:51:42
【问题描述】:
我正在测试在 Java 和 C# 的 32 核服务器上生成许多运行相同功能的线程。我使用函数的 1000 次迭代运行应用程序,使用线程池在 1、2、4、8、16 或 32 个线程上进行批处理。
在 1、2、4、8 和 16 个并发线程时,Java 的速度至少是 C# 的两倍。然而,随着线程数量的增加,差距缩小,C# 的平均运行时间几乎相同,增加了 32 个线程,但 Java 偶尔需要 2000 毫秒(而两种语言通常运行大约 400 毫秒)。 Java 开始变得更糟,每个线程迭代所花费的时间大幅增加。
编辑这是 Windows Server 2008
EDIT2 我已更改以下代码以显示使用执行器服务线程池。我还安装了 Java 7。
我在热点虚拟机中设置了以下优化:
-XX:+UseConcMarkSweepGC -Xmx 6000
但它仍然没有让事情变得更好。代码之间的唯一区别是我使用下面的线程池和我们使用的 C# 版本:
http://www.codeproject.com/Articles/7933/Smart-Thread-Pool
有没有办法让 Java 更加优化? Perhaos,您能解释一下为什么我会看到性能大幅下降吗?
有没有更高效的 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;
}
}
}
}
【问题讨论】:
-
什么操作系统?视窗?我认为可能是,如果您使用 Mono,您可能会说,但仍然......
-
您为什么要尝试比较这两种语言的性能? java语言的主要目标是企业应用程序,如果你需要性能就用c++。
-
您的应用实际使用了多少个内核?
-
-Xmx 6000 是非法选项(不应该有空格,不带后缀的大小以字节为单位,应该是1024的倍数,并且大于2MB),那怎么办你真的在用吗?
-
你从哪里得到那个 java 线程池?尝试另一个或自己创建线程以消除任何可能的问题可能是有意义的。
标签: c# java .net eclipse jvm-hotspot