假设我有一个Java程序:
//case1
Long first = 1;
Long second = 1;
Long third = first - second;
//case2
Long first = Long.MAX_VALUE;
Long second = 100000L;
Long third = first - second;
这两种情况应该具有完全相同的执行时间,不应该有开销吗?实际操作是在Long右边的每个位上执行的,无论其中包含的值是什么,对吗?
如果我的假设是真的,是否有任何语言并非如此?
编辑:提示这是我们正在使用的16位PIC(C代码)的情况,它计算可变时间内的平均值。在M S和Thom的下面的答案之后,我现在明白,以这种方式引入错误是可能的,因为PIC是在时间敏感的基础上计算关键任务信息。
非常感谢你。
答案 0 :(得分:2)
你所说的在Java中是正确的 - 操作在与值无关的时间内执行。在某些语言(例如Lisp)中,如果值超过数据类型的最大合法值,则执行会自动切换为使用“大整数”包,这会大大降低执行速度。
修改强>
第一种和第二种情况之间存在细微差别:值1
是特殊的(因为0)。
Long first=1L;
是:
lconst_1
invokestatic #2; //Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
astore_1
如果常量是(比方说)2L,则得到这个字节代码:
ldc2_w #3; //long 2l
invokestatic #2; //Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
astore_2
由于lconst_1
的运行速度比ldc2_w
快,因此情况1和2之间存在微小的时间差异。
答案 1 :(得分:1)
我不知道,但是我可以设想一种语言,它只是一个“整数”数据类型,根据需要调整整数大小,导致小数字比大数字快。 (考虑Java的BigInteger
类)。
至于那里的代码,由于轻微的异常会导致您使用Long
代替long
,因此这些代码的性能完全不同将为Long
和first
获得预先制作的second
,而其他人必须在第二个示例中创建。{/ p>
如果您在第一个示例中使用200
和201
以及在第二个示例中使用10000000000
和100000000001
,则它们将完全相同。
答案 2 :(得分:1)
它不依赖于语言,而是取决于底层硬件。寄存器大小和数据总线宽度。
例如,如果在16位机器中Long.MAX_VALUE大于16位,则需要2个周期将数据加载到存储器中,因此情况1和情况2将具有不同的执行时间。
通常这些最大值是根据机器位大小设置的
答案 3 :(得分:1)
也许不是答案,但在32位计算机上,64位值不是线程安全的,因为它必须将一半的值放在寄存器中并计算,然后是另一半。可能会有一个优化会忽略值的全零部分,因此对于较小的数字会更快。