我正在一个简单的基准测试中,在几个Linux机器上测试Mono的Java ParallelFX。 .NET的测试在Windows和Linux上都可以很好地运行,但是我对Java版本有点迷恋...
我可以看到指定数量的线程正在启动,但是它们以奇怪的方式运行。它的行为就像它们启动时一样,但是它们完成得非常缓慢。他们继续开始,但要永远完成。似乎它应该超出线程池的限制,而我的CPU使用率对我来说似乎仅使用一个或两个内核(我有i7处理器,因此应尝试使用类似8的处理器)。
是的,我知道我的整数和其他可能不是“线程安全的”。我现在不在乎。这里更大的问题。
C#版本
public class Program
{
static void Main(string[] args)
{
const int numberOfCycles = 1000;
const int numbersPerCycle = 1000000;
Stopwatch swG = Stopwatch.StartNew();
int threadCount = 0;
int completeCount = 0;
Parallel.For(0, numberOfCycles, x =>
{
Console.WriteLine(string.Format("Starting cycle {0}. Thread count at {1}", x, threadCount++));
Random r = new Random();
Stopwatch sw = Stopwatch.StartNew();
List<double> numbers = new List<double>();
for (int i = 0; i < numbersPerCycle; i++)
{
numbers.Add(r.NextDouble() * 1000);
}
numbers.Sort();
double min = numbers.Min();
double max = numbers.Max();
completeCount++;
Console.WriteLine(string.Format("{0} cycles complete: {1:#,##0.0} ms. Min: {2:0.###} Max: {3:0.###}", completeCount, sw.ElapsedMilliseconds, min, max));
threadCount--;
});
Console.WriteLine(string.Format("All {0} cycles complete. Took {1:#,##0.0} ms.", numberOfCycles, swG.ElapsedMilliseconds));
Console.WriteLine("Press any key to continue.");
Console.ReadKey();
}
}
Java版本
附言我很懒,从这里偷走了秒表类:Is there a stopwatch in Java?
public class JavaMonoTest {
static int threadCount = 0;
static int completeCount = 0;
static String CLRF = "\r\n";
public static void main(String[] args) throws IOException, InterruptedException {
final int numberOfCycles = 1000;
final int numbersPerCycle = 1000000;
final int NUM_CORES = Runtime.getRuntime().availableProcessors();
//Setup the running array
List<Integer> cyclesList = new LinkedList<Integer>();
for(int i = 0; i < numberOfCycles; i++){
cyclesList.add(i);
}
Stopwatch swG = new Stopwatch();
swG.start();
ExecutorService exec = Executors.newFixedThreadPool(NUM_CORES);
try {
for (final Integer x : cyclesList) {
exec.submit(new Runnable() {
@Override
public void run() {
System.out.printf("Starting cycle %s. Thread count at %s %s", x, threadCount++, CLRF);
Random r = new Random();
Stopwatch sw = new Stopwatch();
sw.start();
List<Double> numbers = new LinkedList<Double>();
for (int i = 0; i < numbersPerCycle; i++)
{
numbers.add(r.nextDouble() * 1000);
}
Collections.sort(numbers);
double min = Collections.min(numbers);
double max = Collections.max(numbers);
completeCount++;
System.out.printf("%s cycles complete: %.2f ms. Min: %.2f Max: %.2f %s", completeCount, sw.getElapsedTime(), min, max, CLRF);
threadCount--;
}
});
}
} finally {
exec.shutdown();
}
exec.awaitTermination(1, TimeUnit.DAYS);
System.out.printf("All %s cycles complete. Took %.2f ms. %s", numberOfCycles, swG.getElapsedTime(), CLRF);
System.out.println("Press any key to continue.");
System.in.read();
}
}
更新了C#版本以匹配答案中的Java版本
public class Program
{
static void Main(string[] args)
{
const int numberOfCycles = 1000;
const int numbersPerCycle = 1000000;
Stopwatch swG = Stopwatch.StartNew();
int threadCount = 0;
int completeCount = 0;
Parallel.For(0, numberOfCycles, x =>
{
Console.WriteLine(string.Format("Starting cycle {0}. Thread count at {1}", x, Interlocked.Increment(ref threadCount)));
Random r = new Random();
Stopwatch sw = Stopwatch.StartNew();
double[] numbers = new double[numbersPerCycle];
for (int i = 0; i < numbersPerCycle; i++)
{
numbers[i] = r.NextDouble() * 1000;
}
Array.Sort(numbers);
double min = numbers[0];
double max = numbers[numbers.Length - 1];
Interlocked.Increment(ref completeCount);
Console.WriteLine(string.Format("{0} cycles complete: {1:#,##0.0} ms. Min: {2:0.###} Max: {3:0.###}", completeCount, sw.ElapsedMilliseconds, min, max));
Interlocked.Decrement(ref threadCount);
});
Console.WriteLine(string.Format("All {0} cycles complete. Took {1:#,##0.0} ms.", numberOfCycles, swG.ElapsedMilliseconds));
Console.WriteLine("Press any key to continue.");
Console.ReadKey();
}
}
参考方案
运行该程序,我发现它使用了8 cpus的97%-98%,而且还会产生大量的垃圾。如果我使程序更有效,则它可以更快地完成。
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class JavaMonoTest {
static final AtomicInteger threadCount = new AtomicInteger();
static final AtomicInteger completeCount = new AtomicInteger();
public static void main(String[] args) throws InterruptedException {
final int numberOfCycles = 1000;
final int numbersPerCycle = 1000000;
final int NUM_CORES = Runtime.getRuntime().availableProcessors();
long swG = System.nanoTime();
ExecutorService exec = Executors.newFixedThreadPool(NUM_CORES);
try {
for (int i = 0; i < numberOfCycles; i++) {
final int x = i;
exec.submit(new Runnable() {
@Override
public void run() {
try {
System.out.printf("Starting cycle %s. Thread count at %s %n", x, threadCount.getAndIncrement());
Random r = new Random();
long sw = System.nanoTime();
double[] numbers = new double[numbersPerCycle];
for (int i = 0; i < numbersPerCycle; i++) {
numbers[i] = r.nextDouble() * 1000;
}
Arrays.sort(numbers);
double min = numbers[0];
double max = numbers[numbers.length - 1];
completeCount.getAndIncrement();
System.out.printf("%s cycles complete: %.2f ms. Min: %.2f Max: %.2f %n",
completeCount, (System.nanoTime() - sw) / 1e6, min, max);
threadCount.getAndDecrement();
} catch (Throwable t) {
t.printStackTrace();
}
}
});
}
} finally {
exec.shutdown();
}
exec.awaitTermination(1, TimeUnit.DAYS);
System.out.printf("All %s cycles complete. Took %.2f ms. %n",
numberOfCycles, (System.nanoTime() - swG) / 1e6);
}
}
版画
Starting cycle 0. Thread count at 0
Starting cycle 7. Thread count at 7
Starting cycle 6. Thread count at 6
... deleted ...
999 cycles complete: 139.28 ms. Min: 0.00 Max: 1000.00
1000 cycles complete: 139.05 ms. Min: 0.00 Max: 1000.00
All 1000 cycles complete. Took 19431.14 ms.
当回复有时是一个对象有时是一个数组时,如何在使用改造时解析JSON回复? - java我正在使用Retrofit来获取JSON答复。这是我实施的一部分-@GET("/api/report/list") Observable<Bills> listBill(@Query("employee_id") String employeeID); 而条例草案类是-public static class…
改造正在返回一个空的响应主体 - java我正在尝试使用Retrofit和Gson解析一些JSON。但是,我得到的响应机构是空的。当我尝试从对象中打印信息时,出现NullPointerException。我确保URL正确,并且我也确保POJO也正确。我正在使用jsonschema2pojo来帮助创建POJO类。这是我要解析的JSON{ "?xml": { "@versi…
每个文件合并后添加换行 - python我有很多类似以下内容的JSON文件:例如。1.json{"name": "one", "description": "testDescription...", "comment": ""} test.json{"name"…
在PHP中使用long int - php我正在尝试此方法,但无法存储较大的价值$var = rand(100000000000000,999999999999999); echo $var; // prints a 9 digit value(largest possible) 如何获得期望值? 参考方案 PHP整数通常为32位。其他软件包提供了更高精度的整数:http://php.net/man…
您如何在列表内部调用一个字符串位置? - python我一直在做迷宫游戏。我首先决定制作一个迷你教程。游戏开发才刚刚开始,现在我正在尝试使其向上发展。我正在尝试更改PlayerAre变量,但是它不起作用。我试过放在列表内和列表外。maze = ["o","*","*","*","*","*",…