[英]Why is modulo 3 inefficient?
漸近復雜度顯然是相同的(它是恆定時間)。 另一方面,模2很容易以二進制形式實現。 模3稍微復雜一些。
給定任意數字n
, n % 2
可以為0
或1
,因此您要做的就是保留最后一位的值。 您可以使用一個非常簡單的二進制AND來執行此操作:
n % 2 == n & 1
在另一方面,如果你做n % 3
,所有有效的答案是(二進制) 00
, 01
和10
。 請注意,現在答案跨越了兩位。 但是,並非所有兩位數字都是有效的(二進制數11
不能是n % 3
的結果)。 因此,您需要執行額外的操作:
// 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
我不知道模數3是如何在硬件中實現的,但是不管模數3是如何實現的,它都將比模數2稍微復雜一些。也就是說,認為您可以進行更有效的模數運算是很愚蠢的在軟件中比在硬件中已經可用
在匯編級別,模數是通過指令DIV來實現的,對於指令DIV而言,它的速度可能比使用邏輯運算,移位和分支慢。
DIV指令(和帶符號的IDIV的對應IDIV)給出商和余數(模)。 DIV r16通過16位操作數對DX:AX中的32位數字進行潛水,並將商存儲在AX中,將余數存儲在DX中。
它在下面不執行相同的操作嗎?
否,因為代碼不正確:使用輸入21
嘗試,它將返回false
。 但是21 % 3
是0
。
21
是0b10101
。 這意味着在while循環之后,鏈接算法的oddCtr = 3
, evenCtr = 0
。 因為3 != 0
,算法返回false
。
該Java代碼不會轉換為相同的機器代碼。 移位和與運算比本機代碼中的模運算要快。 該示例代碼將解析為本機代碼,並在每次需要時調用。
這是一個證明http://blog.teamleadnet.com/2012/07/faster-division-and-modulo-operation.html
即使這樣,您也不應過度優化代碼而不是提高可讀性。 僅應在關鍵組件上進行優化,並且在所有內容都設置好之后,不僅可以從理論上實際評估收益。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.