简体   繁体   English

为什么模3效率低下?

[英]Why is modulo 3 inefficient?

I have this code here. 在这里有这段代码 This code is called 'efficient' because it is more efficient than modulo 3. 该代码被称为“高效”,因为它比模3更高效。

But why is modulo 3 inefficient? 但是为什么模3效率低下? Does it not do the same operations underneath? 它在下面不执行相同的操作吗? Whats the complexity of modulo operation? 模运算的复杂性是什么?

The asymptotic complexity is obviously the same (it is constant time). 渐近复杂度显然是相同的(它是恒定时间)。 On the other hand, modulo 2 is very easy to implement in binary; 另一方面,模2很容易以二进制形式实现。 modulo 3 is slightly more complicated. 模3稍微复杂一些。

Given any number n , n % 2 can be either 0 or 1 , so all you have to do is keep the value of the last bit. 给定任意数字nn % 2可以为01 ,因此您要做的就是保留最后一位的值。 You can do this with one very simple binary AND: 您可以使用一个非常简单的二进制AND来执行此操作:

n % 2 == n & 1

On the other hand, if you do n % 3 , all valid answers are (in binary) 00 , 01 and 10 . 在另一方面,如果你做n % 3 ,所有有效的答案是(二进制) 000110 Notice that now the answer spans two bits; 请注意,现在答案跨越了两位。 however, not all two bit numbers are valid (binary 11 cannot be the result of n % 3 ). 但是,并非所有两位数字都是有效的(二进制数11不能是n % 3的结果)。 For this reason, you need to do an extra operation: 因此,您需要执行额外的操作:

// 3DEC == 11BIN, so (n & 3) keeps the last two bits of n. You
// then have to ensure that these last two bits are not both 1.
n % 3 == n & 3, if (n & 3) != 3

I don't know how modulo 3 is implemented in hardware, but regardless of how it is implemented, it is going to be slightly more complicated than modulo 2. That being said, it's silly to think that you can make a more efficient modulo operation in software than the one that is already available in hardware. 我不知道模数3是如何在硬件中实现的,但是不管模数3是如何实现的,它都将比模数2稍微复杂一些。也就是说,认为您可以进行更有效的模数运算是很愚蠢的在软件中比在硬件中已经可用

In the assembly level modulo is implemented with the instruction DIV which for large numbers can be slower than using logical operations, shifts and branches. 在汇编级别,模数是通过指令DIV来实现的,对于指令DIV而言,它的速度可能比使用逻辑运算,移位和分支慢。

The DIV instruction (and it's counterpart IDIV for signed numbers) gives both the quotient and remainder (modulo). DIV指令(和带符号的IDIV的对应IDIV)给出商和余数(模)。 DIV r16 dives a 32-bit number in DX:AX by a 16-bit operand and stores the quotient in AX and the remainder in DX. DIV r16通过16位操作数对DX:AX中的32位数字进行潜水,并将商存储在AX中,将余数存储在DX中。

Does it not do the same operations underneath? 它在下面不执行相同的操作吗?

No, because the code is not correct: Try it out with input 21 and it will return false . 否,因为代码不正确:使用输入21尝试,它将返回false However 21 % 3 is 0 . 但是21 % 30

21 is 0b10101 . 210b10101 That means the linked algorithm has oddCtr = 3 and and evenCtr = 0 after the while loop. 这意味着在while循环之后,链接算法的oddCtr = 3evenCtr = 0 Because 3 != 0 the algorithm returns false . 因为3 != 0 ,算法返回false

That java code does not translate to the same machine code. 该Java代码不会转换为相同的机器代码。 Shift and AND operations are faster than modulo in native code. 移位和与运算比本机代码中的模运算要快。 The example code is parsed to native code and called every time is needed. 该示例代码将解析为本机代码,并在每次需要时调用。

Here is a proof http://blog.teamleadnet.com/2012/07/faster-division-and-modulo-operation.html 这是一个证明http://blog.teamleadnet.com/2012/07/faster-division-and-modulo-operation.html

Even so, you should not over optimize code over readability. 即使这样,您也不应过度优化代码而不是提高可读性。 Optimizations should be made only on critical components and after everything is set in place and the benefit can be measured practically not only in theory. 仅应在关键组件上进行优化,并且在所有内容都设置好之后,不仅可以从理论上实际评估收益。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么这种并行矩阵加法效率如此低下? - Why is this parallel matrix addition so inefficient? 为什么if(variable1%variable2 == 0)效率低下? - Why is if (variable1 % variable2 == 0) inefficient? 为什么在 java 中的 for 循环中使用 f.length() 效率如此之低? - Why is using f.length() in a for loop so inefficient in java? 为什么ruby modulo与java / other lang不同? - Why ruby modulo is different from java/other lang ? 为什么模运算在Java VS Perl中会产生不同的结果? - Why does modulo operation gives different results in Java VS Perl? 为什么一个 function 用于 MD5 hash 计算更适合较小的文件,但对于大文件效率低下? - Why is one function for an MD5 hash calculation preferable for smaller files yet inefficient for large files? 为什么 AND(&) 运算符用于计算 Hashmap 中的最终索引 为什么不用 modulo(%) 运算符,即 hashValue & () - Why AND(&) operator used calculating final index in Hashmap why not modulo(%) operator i.e hashValue & () 为什么将较大变量的类型转换为较小的变量会导致较大变量的模数为较小变量的范围 - Why Type Casting of larger variable to smaller variable results in modulo of larger variable by the range of smaller variable 为什么取模运算结果采用被除数的类型而不是除数的类型? - Why do the modulo operation result take the dividend's type instead of the divisor's type? 效率不高的存储桶排序? - Inefficient bucket sort?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM