正在查看几个不同的线程,以获取有关int和float数据类型之间不同类型的数学和转换的一些信息。长话短说我厌倦了阅读每个人的话,没有任何测试来支持任何事情。因此,我提供了相反的内容,在这里我为一个Android应用程序编写了一个小测试,该应用程序实际上是在一个活动中持续动画的活动中运行的(在我看来更为现实,至少对于游戏开发者而言)。我想对这个抽象有所了解,这里是我的Droid运行版本2.2.2的代码和LogCat结果:
结果:
NumberOfLoops = 100,000
LogCat:
06-28 00:17:40.439: DEBUG/MATH.TEST(3417): i=Math.Round(f): 83ms
06-28 00:17:40.439: DEBUG/MATH.TEST(3417): i=(int)f: 4ms
06-28 00:17:40.439: DEBUG/MATH.TEST(3417): f=6666f: 2ms
06-28 00:17:40.439: DEBUG/MATH.TEST(3417): f=(float)6666: 3ms
06-28 00:17:40.439: DEBUG/MATH.TEST(3417): int division: 5ms
06-28 00:17:40.439: DEBUG/MATH.TEST(3417): float division: 10ms
06-28 00:17:40.439: DEBUG/MATH.TEST(3417): int/float division: 14ms
-----------------------------------------------------------------------
06-28 00:18:03.017: DEBUG/MATH.TEST(3417): i=Math.Round(f): 102ms
06-28 00:18:03.017: DEBUG/MATH.TEST(3417): i=(int)f: 3ms
06-28 00:18:03.017: DEBUG/MATH.TEST(3417): f=6666f: 2ms
06-28 00:18:03.017: DEBUG/MATH.TEST(3417): f=(float)6666: 2ms
06-28 00:18:03.017: DEBUG/MATH.TEST(3417): int division: 5ms
06-28 00:18:03.017: DEBUG/MATH.TEST(3417): float division: 9ms
06-28 00:18:03.017: DEBUG/MATH.TEST(3417): int/float division: 13ms
-----------------------------------------------------------------------
06-28 00:18:04.915: DEBUG/MATH.TEST(3417): i=Math.Round(f): 97ms
06-28 00:18:04.915: DEBUG/MATH.TEST(3417): i=(int)f: 2ms
06-28 00:18:04.915: DEBUG/MATH.TEST(3417): f=6666f: 2ms
06-28 00:18:04.915: DEBUG/MATH.TEST(3417): f=(float)6666: 2ms
06-28 00:18:04.915: DEBUG/MATH.TEST(3417): int division: 5ms
06-28 00:18:04.915: DEBUG/MATH.TEST(3417): float division: 9ms
06-28 00:18:04.923: DEBUG/MATH.TEST(3417): int/float division: 13ms
NumberOfLoops = 1,000,0000
LogCat:
06-28 00:20:09.993: DEBUG/MATH.TEST(3454): i=Math.Round(f): 7569ms
06-28 00:20:09.993: DEBUG/MATH.TEST(3454): i=(int)f: 236ms
06-28 00:20:09.993: DEBUG/MATH.TEST(3454): f=6666f: 223ms
06-28 00:20:09.993: DEBUG/MATH.TEST(3454): f=(float)6666: 209ms
06-28 00:20:09.993: DEBUG/MATH.TEST(3454): int division: 474ms
06-28 00:20:09.993: DEBUG/MATH.TEST(3454): float division: 907ms
06-28 00:20:09.993: DEBUG/MATH.TEST(3454): int/float division: 1332ms
-----------------------------------------------------------------------
06-28 00:20:34.087: DEBUG/MATH.TEST(3454): i=Math.Round(f): 7533ms
06-28 00:20:34.087: DEBUG/MATH.TEST(3454): i=(int)f: 235ms
06-28 00:20:34.087: DEBUG/MATH.TEST(3454): f=6666f: 201ms
06-28 00:20:34.087: DEBUG/MATH.TEST(3454): f=(float)6666: 201ms
06-28 00:20:34.095: DEBUG/MATH.TEST(3454): int division: 470ms
06-28 00:20:34.095: DEBUG/MATH.TEST(3454): float division: 912ms
06-28 00:20:34.095: DEBUG/MATH.TEST(3454): int/float division: 1325ms
-----------------------------------------------------------------------
06-28 00:21:08.876: DEBUG/MATH.TEST(3454): i=Math.Round(f): 7527ms
06-28 00:21:08.876: DEBUG/MATH.TEST(3454): i=(int)f: 235ms
06-28 00:21:08.876: DEBUG/MATH.TEST(3454): f=6666f: 208ms
06-28 00:21:08.876: DEBUG/MATH.TEST(3454): f=(float)6666: 201ms
06-28 00:21:08.884: DEBUG/MATH.TEST(3454): int division: 469ms
06-28 00:21:08.884: DEBUG/MATH.TEST(3454): float division: 905ms
06-28 00:21:08.884: DEBUG/MATH.TEST(3454): int/float division: 1333ms
代码:
long mathRoundTime = 0L;
long castingIntTime = 0L;
long usingFTime = 0L;
long castingFloatTime = 0L;
long integerMathTime = 0L;
long floatMathTime = 0L;
long mixedMathTime = 0L;
long mTimerDelta=0L;
long mTimerFinish = 0L;
final int maxCycles=10000000;
int x=0;
int iTest=0;
int i1=6666;
int i2=2;
float fTest=0f;
float f1=6666f;
float f2=2f;
// Test the int -Math.round- float
long mTimerStart = System.currentTimeMillis();
for (x=0;x<maxCycles;x++){
iTest = Math.round(fTest);
}
mTimerFinish = System.currentTimeMillis();
mTimerDelta = mTimerFinish - mTimerStart;
mathRoundTime = mTimerDelta;
// Test the int casting from Float
mTimerStart = System.currentTimeMillis();
for (x=0;x<maxCycles;x++){
iTest = (int)(fTest);
}
mTimerFinish = System.currentTimeMillis();
mTimerDelta = mTimerFinish - mTimerStart;
castingIntTime = mTimerDelta;
// casting from int with f
mTimerStart = System.currentTimeMillis();
for (x=0;x<maxCycles;x++){
fTest = 6666f;
}
mTimerFinish = System.currentTimeMillis();
mTimerDelta = mTimerFinish - mTimerStart;
usingFTime = mTimerDelta;
// casting from int with f
mTimerStart = System.currentTimeMillis();
for (x=0;x<maxCycles;x++){
fTest = (float)6666;
}
mTimerFinish = System.currentTimeMillis();
mTimerDelta = mTimerFinish - mTimerStart;
castingFloatTime = mTimerDelta;
// casting from int with f
mTimerStart = System.currentTimeMillis();
for (x=0;x<maxCycles;x++){
iTest = i1/i2;
}
mTimerFinish = System.currentTimeMillis();
mTimerDelta = mTimerFinish - mTimerStart;
integerMathTime = mTimerDelta;
// casting from int with f
mTimerStart = System.currentTimeMillis();
for (x=0;x<maxCycles;x++){
fTest = f1/f2;
}
mTimerFinish = System.currentTimeMillis();
mTimerDelta = mTimerFinish - mTimerStart;
floatMathTime = mTimerDelta;
// casting from int with f
mTimerStart = System.currentTimeMillis();
for (x=0;x<maxCycles;x++){
fTest = i1/f2;
}
mTimerFinish = System.currentTimeMillis();
mTimerDelta = mTimerFinish - mTimerStart;
mixedMathTime = mTimerDelta;
Log.d("MATH.TEST", " i=Math.Round(f): " + Long.toString(mathRoundTime) + "ms");
Log.d("MATH.TEST", " i=(int)f: " + Long.toString(castingIntTime)+ "ms");
Log.d("MATH.TEST", " f=6666f: " + Long.toString(usingFTime)+ "ms");
Log.d("MATH.TEST", " f=(float)6666: " + Long.toString(castingFloatTime)+ "ms");
Log.d("MATH.TEST", " int division: " + Long.toString(integerMathTime)+ "ms");
Log.d("MATH.TEST", " float division: " + Long.toString(floatMathTime)+ "ms");
Log.d("MATH.TEST", "int/float division: " + Long.toString(mixedMathTime)+ "ms");
我很乐意听到一些关于为什么会有这样的事情的讨论......如果出现问题,请告诉我,我可以重新运行并发布。否则继续自己做,我只是想分享我的发现。
答案 0 :(得分:0)
这看起来对我有点好笑。您的简单示例的时间安排如下:
for (x=0;x<maxCycles;x++){
iTest = (int)(fTest);
}
waaaay太低了。我强烈怀疑他们要么被内联,要么将转换移到循环体外。您是否可以尝试在循环时fTest随i变化的情况下运行它?否则,如果JVM能够快速测量,您将无法获得准确的测量结果。
答案 1 :(得分:0)
这些肯定是一些非常有趣的发现。但我怀疑JVM是否优化了循环。看看代码是否扩展会很有趣。 (当C仍然流行并且每个CPU时钟都很重要时,循环扩展曾经是一种优化技术)
e.g
final int cycles = maxCycles / 100
for (x=0;x<cycles;x++){
fTest = 6666f;
fTest = 6666f;
... 100 times ...
fTest = 6666f;
fTest = 6666f;
}
或者,如果可能的话,甚至进行1000次......甚至更进一步:编写一个程序来生成源代码,使每一行都有一个唯一的编号,以排除JVM可能的任何优化。