我正在编写一个使用Dijkstra算法查找图中最小路径的应用程序。图中节点和边的权重是float
个数,因此算法在浮点数上做了很多算术。如果我将所有重量都转换为int
s,我可以改善运行时间吗?在Java中,int算术运算是否比浮动运算更快?
我试着写一个简单的基准来检查出来,但我对我得到的结果不满意。可能编译器优化了程序的某些部分,因此结果对我来说看起来不太好。
编辑:
我正在尝试解决的问题是在信息检索字段中。应用程序应显示作为一组关键字提出的查询的答案。
我的数据结构是加权有向图。给定一组叶节点,我必须找到连接这些节点并向用户显示答案的最小树。权重由部分基于tf / idf技术的加权函数指定。用户不知道我分配给节点和边缘的权重,他只想看到与他提出的查询相关的答案。因此不需要精确的结果,只需根据他们的权重枚举答案。只是本地使用加权函数(正如我提到它基于tf / idf)给出浮点权重,所以我到目前为止使用了浮点数。
我希望这会为这个问题增加一些背景知识。
答案 0 :(得分:2)
对于简单操作int更快,但是对于int,您可能需要做更多工作才能获得相同的结果。 e.g。
as float
float f = 15 * 0.987;
as int
int i = 15 * 987 / 1000;
额外除法意味着int操作可能需要更长时间。
答案 1 :(得分:1)
与此类事情一样,您应该为自己设定一些性能目标,然后对应用进行概要分析以确定它是否符合这些目标。
很多时候你会发现令人惊讶的结果;所用的时间几乎不受基础数字类型的影响,或者你的算法不是最理想的。
关于编译器优化 - 它们是性能优化的真实且有效的部分。
如果使用类型A理论上比使用类型B更快,但是你的编译器可以在真实场景中更快地优化类型B,那么这是一个有价值的证据,而不是消失的来源。
答案 2 :(得分:1)
在我的机器上,整数减法比双减法快2.5倍。 然而,整数乘法仅比双乘法快约1.5倍。
以下测试适用于随机数据,这可能会阻止编译器进行优化。
// test whether int subs are faster than double subs
public void compareIntAndFloatSubtraction(){
int N = 100000; // input array size
int k = 100000; // number of mathematical operations performed on each element
// generate random data
int[] ints = new int[N];
double[] doubles = new double[N];
Random r = new Random(1l);
for (int i = 0; i < N; i++) {
ints[i] = r.nextInt();
doubles[i] = r.nextDouble();
}
// measure integer subtractions
long before = System.currentTimeMillis();
for (int i = 1; i < N; i++) {
for (int j = 0; j < k; j++) {
ints[i] -= ints[i-1]; // referring to another element might prevent from optimization also
}
}
System.out.println(String.format("time needed for int subs [ms]: %s", System.currentTimeMillis()-before));
// measure double subtractions
before = System.currentTimeMillis();
for (int i = 1; i < N; i++) {
for (int j = 0; j < k; j++) {
doubles[i] -= doubles[i-1];
}
}
System.out.println(String.format("time needed for double subs [ms]: %s", System.currentTimeMillis()-before));
}
答案 3 :(得分:0)
如果你只想比较权重,你应该更喜欢int浮动。
答案 4 :(得分:0)
一般情况下,出于性能原因,您不必担心int
和float
之间的选择。
以下是Java Puzzlers附录中的摘录:
浮点运算是不精确的。不要在需要精确结果的地方使用浮点数;相反,使用整数类型或
BigDecimal
。首选double
至float
。
除非你有充分的理由,否则如果必须使用浮点运算,通常应该更喜欢double
到float
。如果需要确切结果,请继续使用BigDecimal
;它会变慢,因为它不是原始的,但除非分析显示它是不可接受的,这通常是最好的选择。
如果必须使用浮点运算,那么尝试使用int
来优化它是不明智的。这可能是一个过早的优化,只会使代码变得复杂化。以最自然,最可读的方式书写。不要为了轻微的性能提升而不必要地使代码复杂化。
如果您实际上不需要浮点运算,那么请务必使用int
或long
。
答案 5 :(得分:0)
我认为性能在很大程度上取决于算法和运行软件的平台。
如果您正在X86平台上进行矩阵/数组计算,运行时可能会对其进行优化以使用SSE,这是一个浮点/双精度扩展指令集。
在其他平台上,运行时可能会优化到OpenCL(我不相信任何人现在都这样做,但可能会发生:)。我不知道在这样的平台上运行得最快,在什么条件下。可能只是OpenCL针对整数工作负载进行了优化。
在这些情况下,我会得出结论,此时优化数据类型(float或int)并没有用,只是优化代码的可读性。
如果您的代码具有高性能关键性,而且您确切知道系统现在和将来运行的硬件,您可以使用各种算法测试典型工作负载,并选择最符合您需求的工作负载。
但一般来说,只需使用您可以理解的算法,保持代码可读,从而将错误数量降低。如果结果不正确,快速代码的价值不高:)
答案 6 :(得分:-6)
我不这么认为。
Float是4个字节。而java中的Int也是4个字节。
为什么不使用Date(java.util.Date)来获取运行时间?
您可以定义一个拥有100000个节点的图表。然后计算它。