Gần đây tôi đã chạy điểm chuẩn trên Java vs C# cho 1000 tác vụ được lên lịch trên một luồng. Máy chủ có 4 bộ xử lý vật lý, mỗi bộ xử lý có 8 lõi. Hệ điều hành là Server 2008, có 32 GB bộ nhớ và mỗi CPU là một Xeon x7550 Westmere/Nehalem-C.Java vs C# Hiệu suất đa luồng, tại sao Java lại chậm hơn? (đồ thị và mã đầy đủ bao gồm)
Tóm lại, việc triển khai Java nhanh hơn nhiều so với C# ở 4 luồng nhưng chậm hơn nhiều khi số lượng chủ đề tăng lên. Dường như C# đã trở nên nhanh hơn cho mỗi lần lặp lại, khi số lượng chỉ số đã tăng lên. Đồ thị có trong bài này:
Việc thực hiện Java được viết trên một 64bit Hotspot JVM, với Java 7 và sử dụng một dịch vụ Executor threadpool Tôi tìm thấy trực tuyến (xem dưới đây). Tôi cũng đặt JVM thành GC đồng thời.
C# được viết trên .net 3.5 và threadpool đến từ CodeProject: http://www.codeproject.com/Articles/7933/Smart-Thread-Pool
(Tôi đã bao gồm mã dưới đây).
Câu hỏi của tôi:
1) Tại sao Java bị chậm hơn nhưng C# đang nhanh hơn?
2) Tại sao thời gian thực thi của C# dao động đáng kể? (Đây là câu hỏi chính của chúng tôi)
Chúng tôi đã tự hỏi liệu C# biến động là do xe buýt nhớ được maxed ra ....
Mã (Xin đừng làm nổi bật lỗi với khóa, điều này là không thích hợp với tôi nhằm mục đích):
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.TimeUnit;
public class PoolDemo {
static long FastestMemory = 2000000000;
static long SlowestMemory = 0;
static long TotalTime;
static long[] FileArray;
static DataOutputStream outs;
static FileOutputStream fout;
public static void main(String[] args) throws InterruptedException, FileNotFoundException {
int Iterations = Integer.parseInt(args[0]);
int ThreadSize = Integer.parseInt(args[1]);
FileArray = new long[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);
service.execute(t);
}
service.shutdown();
service.awaitTermination(90, TimeUnit.SECONDS);
System.out.println("Fastest: " + FastestMemory);
System.out.println("Average: " + TotalTime/Iterations);
for(int j=0; j<FileArray.length; j++){
new PrintStream(fout).println(FileArray[j] + ",");
}
}
private static class Task implements Runnable {
private int ID;
static Byte myByte = 0;
public Task(int index) {
this.ID = index;
}
@Override
public void run() {
long Start = System.nanoTime();
int Size1 = 10000000;
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.nanoTime();
long Duration = Finish - Start;
FileArray[this.ID] = Duration;
TotalTime += Duration;
System.out.println("Individual Time " + this.ID + " \t: " + (Duration) + " nanoseconds");
if(Duration < FastestMemory){
FastestMemory = Duration;
}
if (Duration > SlowestMemory)
{
SlowestMemory = Duration;
}
}
}
}
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Amib.Threading;
using System.Diagnostics;
using System.IO;
using System.Runtime;
namespace ServerTesting
{
class Program
{
static long FastestMemory = 2000000000;
static long SlowestMemory = 0;
static long TotalTime = 0;
static int[] FileOutput;
static byte myByte = 56;
static System.IO.StreamWriter timeFile;
static System.IO.StreamWriter memoryFile;
static void Main(string[] args)
{
Console.WriteLine("Concurrent GC enabled: " + GCSettings.IsServerGC);
int Threads = Int32.Parse(args[1]);
int Iterations = Int32.Parse(args[0]);
timeFile = new System.IO.StreamWriter(Threads + "_" + Iterations + "_" + "time.csv");
FileOutput = new int[Iterations];
TestMemory(Threads, Iterations);
for (int j = 0; j < Iterations; j++)
{
timeFile.WriteLine(FileOutput[j] + ",");
}
timeFile.Close();
Console.ReadLine();
}
private static void TestMemory(int threads, int iterations)
{
SmartThreadPool pool = new SmartThreadPool();
pool.MaxThreads = threads;
Console.WriteLine("Launching " + iterations + " calculators with " + pool.MaxThreads + " threads");
for (int i = 0; i < iterations; i++)
{
pool.QueueWorkItem(new WorkItemCallback(MemoryIntensiveTask), i);
}
pool.WaitForIdle();
double avg = TotalTime/iterations;
Console.WriteLine("Avg Memory Time : " + avg);
Console.WriteLine("Fastest: " + FastestMemory + " ms");
Console.WriteLine("Slowest: " + SlowestMemory + " ms");
}
private static object MemoryIntensiveTask(object args)
{
DateTime start = DateTime.Now;
int Size1 = 10000000;
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;
}
DateTime finish = DateTime.Now;
TimeSpan ts = finish - start;
long duration = ts.Milliseconds;
Console.WriteLine("Individual Time " + args + " \t: " + duration);
FileOutput[(int)args] = (int)duration;
TotalTime += duration;
if (duration < FastestMemory)
{
FastestMemory = duration;
}
if (duration > SlowestMemory)
{
SlowestMemory = duration;
}
return null;
}
}
}
đã bạn nhận thấy rằng trong Java vòng lặp của bạn tạo ra một 'PrintStream' trong mỗi lần lặp trong khi trong 'C#' bạn mở 'StreamWriter' chỉ một lần? Tôi không nghĩ rằng nó giải thích hiện tượng này, nhưng thử nghiệm của bạn không chính xác 100% ở mức cơ bản. – RonK
Bạn đã thử lớp ThreadPoolExecutor chưa? ThreadPoolExecutor được cho là cung cấp hiệu suất được cải thiện cho số lượng lớn các tác vụ không đồng bộ. – ChadNC
@ ChanNC- cảm ơn tôi sẽ thử điều đó. – mezamorphic