给出以下代码段:
int[] arr = {1, 2, 3};
for (int i : arr)
System.out.println(i);
Run Code Online (Sandbox Code Playgroud)
我有以下问题:
List<String> flowers = new ArrayList<String>();
Run Code Online (Sandbox Code Playgroud)
我的for循环目前看起来像这样......
for (int i = 0; i < flowers.size(); i++) {
...
}
Run Code Online (Sandbox Code Playgroud)
或者我应该改变它看起来像下面给出的代码
int size = flowers.size();
for (int i = 0; i < size; i++) {
...
}
Run Code Online (Sandbox Code Playgroud)
哪个性能更高(假设我有大量的花),我猜它应该是后者.
在Java中,以老式的方式迭代数组是否更快,
for (int i = 0; i < a.length; i++)
f(a[i]);
Run Code Online (Sandbox Code Playgroud)
或者使用更简洁的表格,
for (Foo foo : a)
f(foo);
Run Code Online (Sandbox Code Playgroud)
对于ArrayList,答案是否相同?
当然,对于大量的应用程序代码,答案是它没有明显的区别,因此应该使用更简洁的表单来提高可读性.然而,我正在研究的背景是重型技术计算,必须执行数十亿次操作,因此即使很小的速度差异也可能最终显着.
(对于那些熟悉JVM编译和优化技巧的人来说一个问题...... :-)
是否有任何"for"和"foreach"模式明显优于其他模式?
考虑以下两个例子:
public void forLoop(String[] text)
{
if (text != null)
{
for (int i=0; i<text.length; i++)
{
// Do something with text[i]
}
}
}
public void foreachLoop(String[] text)
{
if (text != null)
{
for (String s : text)
{
// Do something with s, exactly as with text[i]
}
}
}
Run Code Online (Sandbox Code Playgroud)
是forLoop快还是慢foreachLoop?
假设在这两种情况下text阵列都不需要进行任何健全性检查,是否有明显的赢家或仍然太接近无法拨打电话?
编辑:正如在一些答案中所指出的,对于数组,性能应该是相同的,而对于像List这样的抽象数据类型,"foreach"模式可能略微更好.另请参阅讨论该主题的答案.
我发现将一个短数组转换为字节数组,将字节数组转换为短数组,但不是短数组转换为字节数组.
以下是导致转换的代码
while(!stopped)
{
Log.i("Map", "Writing new data to buffer");
short[] buffer = buffers[ix++ % buffers.length];
N = recorder.read(buffer,0,buffer.length);
track.write(buffer, 0, buffer.length);
byte[] bytes2 = new byte[N];
Run Code Online (Sandbox Code Playgroud)
我试过了
int i = 0;
ByteBuffer byteBuf = ByteBuffer.allocate(N);
while (buffer.length >= i) {
byteBuf.putShort(buffer[i]);
i++;
}
bytes2 = byteBuf.array();
Run Code Online (Sandbox Code Playgroud)
和
ByteBuffer.wrap(bytes2).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(buffer);
Run Code Online (Sandbox Code Playgroud)
但是我在两者上都收到了这个错误(错误如果不完全相同但两者非常相似):
05-29 13:41:12.021:W/AudioTrack(9758):gainBuffer()轨道0x30efa0禁用,重启
05-29 13:41:12.857:W/AudioWorker(9758):读取语音AudioWorker时出错
05-29 13:41:12.857:W/AudioWorker(9758):java.nio.BufferOverflowException
05-29 13:41:12.857:W/AudioWorker(9758):at java.nio.ShortBuffer.put(ShortBuffer.java:422)
05-29 13:41:12.857:W/AudioWorker(9758):at java.nio.ShortToByteBufferAdapter.put(ShortToByteBufferAdapter.java:210)
05-29 13:41:12.857:W/AudioWorker(9758):at java.nio.ShortBuffer.put(ShortBuffer.java:391)
05-29 13:41:12.857:W/AudioWorker(9758):at com.avispl.nicu.audio.AudioWorker.run(AudioWorker.java:126)
并且只是在这里提供尽可能多的信息是使用字节数组之后的代码
Log.i("Map", "test");
//convert to ulaw
read(bytes2, …Run Code Online (Sandbox Code Playgroud) 原始数组上的for循环之间是否存在性能差异?
假设:
double[] doubleArray = new double[300000];
for (double var: doubleArray)
someComplexCalculation(var);
Run Code Online (Sandbox Code Playgroud)
要么 :
for ( int i = 0, y = doubleArray.length; i < y; i++)
someComplexCalculation(doubleArray[i]);
Run Code Online (Sandbox Code Playgroud)
测试结果
我实际上描述了它:
Total timeused for modern loop= 13269ms
Total timeused for old loop = 15370ms
Run Code Online (Sandbox Code Playgroud)
所以现代循环实际上运行得更快,至少在我的Mac OSX JVM 1.5上.
我正在使用带有Android Studio和Retrolambda插件的Java 8将lambdas编译为匿名类(因为Android上不支持Java 8).IDE向我展示了如何更改我的代码以使用Java 8的所有功能的警告(或提示).当您循环收集时,这些功能之一是"可以用foreach调用替换".我想抑制这种警告,但我无法弄清楚如何做到这一点.
抑制这种警告的最简单的解决方案是@SuppressWarnings("all")注释.但是我想要警告不同类型的警告,所以这不是解决方案.
有没有办法为整个IDE或仅为代码块(类似的东西@SuppressWarnings("foreach"))禁用这种警告?
我正在分析我的安卓游戏并惊讶地发现:
for(O o : myArrayList)
{
}
Run Code Online (Sandbox Code Playgroud)
创建一堆堆分配.
除了使用数字i++for循环,还有更好的方法来解决这个问题吗?我可以预先分配我的迭代器吗?
我和我的朋友就此发生了争执.考虑下面的片段,
for(i=0; i<someList.size(); i++) {
//some logic
}
Run Code Online (Sandbox Code Playgroud)
这someList.size()将在每次迭代时执行,因此建议将此大小计算迁移到循环外部(之前).
现在当我像这样使用扩展for循环时会发生什么,
for(SpecialBean bean: someBean.getSpecialList()) {
//some logic
}
Run Code Online (Sandbox Code Playgroud)
是否有必要转移someBean.getSpecialList()到循环外?someBean.getSpecialList()如果我要保留第二个片段,它会执行多少次?
JLS指出,对于数组,“增强的for语句相当于以下形式的基本 for 语句”。但是,如果我检查 JDK8 生成的字节码,对于两种变体都会生成不同的字节码,并且如果我尝试测量性能,令人惊讶的是,增强的字节码似乎给出了更好的结果(在 jdk8 上)...有人可以建议为什么吗? \是吗?我猜这是因为 jmh 测试不正确,所以如果是这样,请建议如何解决这个问题。(我知道 JMH 声明不要使用循环进行测试,但我认为这不适用于此处,因为我实际上是在尝试测量此处的循环)
\n我的 JMH 测试相当简单(可能太简单了),但我无法解释结果。测试JMH代码如下,典型结果为:
\nJdkBenchmarks.enhanced avgt 5 2556.281 \xc2\xb1 31.789 ns/op\nJdkBenchmarks.indexed avgt 5 4032.164 \xc2\xb1 100.121 ns/op\nRun Code Online (Sandbox Code Playgroud)\n这意味着通常增强的 for 循环速度更快,并且其测量比索引循环更准确,因此我们无法解决测量不确定性的差异。原则上,对于使用随机整数初始化的数组或更大的数组,结果相同。
\npublic class JdkBenchmarks {\n\n @Benchmark\n @BenchmarkMode(AverageTime)\n @OutputTimeUnit(NANOSECONDS)\n public void indexed(Blackhole blackhole, TestState testState) {\n int length = testState.values.length;\n for(int i = 0; i < length; i++) {\n blackhole.consume(testState.values[i]);\n }\n }\n\n @Benchmark\n @BenchmarkMode(AverageTime)\n @OutputTimeUnit(NANOSECONDS)\n public void enhanced(Blackhole blackhole, TestState testState) {\n for …Run Code Online (Sandbox Code Playgroud) java ×9
performance ×4
arrays ×3
android ×2
for-loop ×2
foreach ×2
iteration ×2
coding-style ×1
iterator ×1
java-8 ×1
jmh ×1
optimization ×1