【发布时间】:2013-02-15 06:05:45
【问题描述】:
我对 Java 7 的一般经验告诉我,它比 Java 6 快。但是,我遇到了足够多的信息,这让我相信并非总是如此。
第一条信息来自here 找到的 Minecraft Snooper 数据。我的目的是查看这些数据以确定用于启动 Minecraft 的不同开关的效果。例如,我想知道使用 -Xmx4096m 是否会对性能产生负面或正面影响。在我到达那里之前,我查看了正在使用的不同版本的 Java。它涵盖了从 1.5 到使用 1.8 的开发人员的所有内容。通常,随着您增加 java 版本,您会看到 fps 性能的提高。在 1.6 的不同版本中,您甚至可以看到这种逐渐上升的趋势。老实说,我没想到会在野外看到这么多不同版本的 java,但我猜人们不会像他们应该的那样运行更新。
在 1.6 的更高版本中,您会获得最高的浏览量。 1.7 的平均速度比 1.6 的更高版本低约 10fps,但仍高于 1.6 的早期版本。在我自己的系统中的样本上,几乎不可能看到差异,但在查看更广泛的样本时,就很清楚了。
为了控制有人可能找到了我控制的 Java 魔术开关的可能性,只查看没有传递任何开关的数据。这样我就可以在开始查看不同的标志之前进行合理的控制。
我忽略了我所看到的大部分内容,因为这可能是一些没有与我分享的 Magic Java 6。
现在我一直在处理另一个项目,该项目需要我在 InputStream 中传递一个数组以由另一个 API 处理。最初我使用 ByteArrayInputStream 因为它可以开箱即用。当我查看它的代码时,我注意到每个函数都是同步的。由于这对这个项目来说是不必要的,所以我重写了一个,去掉了同步。然后我决定我想知道在这种情况下同步的一般成本是多少。
我模拟了一个简单的测试只是为了看看。我使用 System.nanoTime() 对所有内容进行计时,并使用 Java 1.6_20 x86 和 1.7.0-b147 AMD64 和 1.7_15 AMD64 并使用 -server。我预计 AMD64 版本仅基于架构就能胜过任何 java 7 优势。我还查看了第 25、第 50 和第 75 个百分位数(蓝色、红色、绿色)。然而,没有 -server 的 1.6 击败了其他所有配置。
所以我的问题是。 1.6 -server 选项中有什么影响性能,在 1.7 中也默认启用?
我知道 1.7 中的大部分速度增强来自于将 1.6 中一些更激进的性能选项默认为开启,但其中之一是导致性能差异。我只是不知道该看哪些。
public class ByteInputStream extends InputStream {
public static void main(String args[]) throws IOException {
String song = "This is the song that never ends";
byte[] data = song.getBytes();
byte[] read = new byte[data.length];
ByteArrayInputStream bais = new ByteArrayInputStream(data);
ByteInputStream bis = new ByteInputStream(data);
long startTime, endTime;
for (int i = 0; i < 10; i++) {
/*code for ByteInputStream*/
/*
startTime = System.nanoTime();
for (int ctr = 0; ctr < 1000; ctr++) {
bis.mark(0);
bis.read(read);
bis.reset();
}
endTime = System.nanoTime();
System.out.println(endTime - startTime);
*/
/*code for ByteArrayInputStream*/
startTime = System.nanoTime();
for (int ctr = 0; ctr < 1000; ctr++) {
bais.mark(0);
bais.read(read);
bais.reset();
}
endTime = System.nanoTime();
System.out.println(endTime - startTime);
}
}
private final byte[] array;
private int pos;
private int min;
private int max;
private int mark;
public ByteInputStream(byte[] array) {
this(array, 0, array.length);
}
public ByteInputStream(byte[] array, int offset, int length) {
min = offset;
max = offset + length;
this.array = array;
pos = offset;
}
@Override
public int available() {
return max - pos;
}
@Override
public boolean markSupported() {
return true;
}
@Override
public void mark(int limit) {
mark = pos;
}
@Override
public void reset() {
pos = mark;
}
@Override
public long skip(long n) {
pos += n;
if (pos > max) {
pos = max;
}
return pos;
}
@Override
public int read() throws IOException {
if (pos >= max) {
return -1;
}
return array[pos++] & 0xFF;
}
@Override
public int read(byte b[], int off, int len) {
if (pos >= max) {
return -1;
}
if (pos + len > max) {
len = max - pos;
}
if (len <= 0) {
return 0;
}
System.arraycopy(array, pos, b, off, len);
pos += len;
return len;
}
@Override
public void close() throws IOException {
}
}// end class
【问题讨论】:
-
+1 表示非常漂亮的图表和有据可查的问题。
-
我有相反的意见。这里有很多废话,还有一个漂亮的图表,但没有真正的内容。如果您刚刚展示了您的代码并在表格中描述了结果,那么将有更多的人能够帮助您。事实上,你可能得到的只是猜测。 -1 如果可以的话。
-
Y 轴是什么?您是否测量了多个重复的任务,而不是一个?您确定 GC 没有干预结果吗?
-
您发布了很多数据和信息,但其中似乎并不相关。我阅读您的问题的次数越多(我已经阅读了好几次),我就越不了解您的问题。发布代码,发布您的测量循环,发布正在测量的部分。除此之外:配置您的代码并检查花费了多少时间。
-
这个问题本来可以短很多。向我们展示有问题的代码,并分享有关您的基准测试过程的更多信息。 真的很容易做到这一点。
标签: java performance inputstream