我有一个用Java 8编写的相当简单的业余爱好项目,它在其一种操作模式中广泛使用重复的Math.round()调用.例如,一个这样的模式产生4个线程,并通过ExecutorService对48个可运行的任务进行排队,每个任务运行类似于下面的代码块2 ^ 31次:
int3 = Math.round(float1 + float2);
int3 = Math.round(float1 * float2);
int3 = Math.round(float1 / float2);
Run Code Online (Sandbox Code Playgroud)
这不完全是如何(涉及数组和嵌套循环),但你明白了.无论如何,在Java 8u40之前,类似于上述代码的代码可以在AMD A10-7700k上在大约13秒内完成大约1030亿个指令块的全部运行.使用Java 8u40,执行相同的操作大约需要260秒.代码没有变化,没有任何变化,只是Java更新.
有没有人注意到Math.round()变得慢得多,特别是当它被重复使用时?几乎就好像JVM正在进行某种优化之前它已经不再做了.也许它是在8u40之前使用SIMD而现在不是?
编辑:我已经完成了对MVCE的第二次尝试.你可以在这里下载第一次尝试:
https://www.dropbox.com/s/rm2ftcv8y6ye1bi/MathRoundMVCE.zip?dl=0
第二次尝试如下.我的第一次尝试已经从这篇文章中删除,因为它被认为太长了,并且很容易被JVM去掉代码去除(显然在8u40中发生的事情更少).
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MathRoundMVCE
{
static long grandtotal = 0;
static long sumtotal = 0;
static float[] float4 = new float[128];
static float[] float5 = new float[128];
static int[] int6 = new int[128];
static int[] int7 = new int[128];
static int[] int8 = new int[128];
static long[] longarray = …Run Code Online (Sandbox Code Playgroud) 标准Math.sqrt()方法在Java中看起来相当快,但它有一个固有的缺点,它总是涉及64位操作,它只会在处理32位float值时降低速度.是否可以使用自定义方法做得更好,该方法使用a float作为参数,仅执行32位操作,并返回float结果?
我看见:
它只是强化了Math.sqrt()通常难以击败的概念.我也看到了:
http://www.codeproject.com/Articles/69941/Best-Square-Root-Method-Algorithm-Function-Precisi
这向我展示了一堆有趣的C++/ASM黑客,我根本无法直接移植到Java.虽然sqrt14作为JNI调用的一部分可能很有趣...
我还查看了Apache Commons FastMath,但看起来该库默认为标准的Math.sqrt(),所以没有帮助.然后是Yeppp!:
但我还没有打扰过它.
我原以为HashMaps对于单个值的随机访问比ArrayLists 更快...也就是说,这HashMap.get(key)应该比ArrayList.get(index)仅仅因为ArrayList必须遍历集合的每个元素以达到其值而更快,而HashMap不是.你知道,O(1)vs O(n)和所有这一切.
编辑:所以我对HashMaps的理解是不充分的,因此我的困惑.此代码的结果符合预期.感谢您的解释.
所以我决定用百灵鸟来测试它.这是我的代码:
import java.util.HashMap;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.Scanner;
public class Testing
{
public static void main(String[] args)
{
ArrayList<SomeClass> alist = new ArrayList<>();
HashMap<Short, SomeClass> hmap = new HashMap<>(4000, (float).75);
ListIterator<SomeClass> alistiterator = alist.listIterator();
short j = 0;
do
{
alistiterator.add(new SomeClass());
j++;
}
while(j < 4000);
for (short i = 0; i < 4000; …Run Code Online (Sandbox Code Playgroud)