Java / Android数学测试:对Int和Float Math / Conversion / Casting感到好奇

时间:2011-06-28 04:33:10

标签: java android math floating-point int

正在查看几个不同的线程,以获取有关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");

我很乐意听到一些关于为什么会有这样的事情的讨论......如果出现问题,请告诉我,我可以重新运行并发布。否则继续自己做,我只是想分享我的发现。

2 个答案:

答案 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可能的任何优化。