julia - 使用 `Int((n+1)/2)` 、 `round(Int, (n+1)/2)` 或 `Int((n+1)//2)` 哪个更好?

标签 julia

我有一个奇数n并想使用 (n+1)/2作为数组索引。计算指数的最佳方法是什么?我刚想出来用Int((n+1)/2) , round(Int, (n+1)/2))Int((n+1)//2) .哪个更好,或者我不需要太担心它们?

最佳答案

为了获得更好的性能,您需要整数除法( div÷ )。 /给出整数参数的浮点结果。 //给出 Rational不是整数。所以你需要写div(n+1, 2)(n+1) ÷ 2 .输入 ÷你可以写\div然后在 julia REPL、Jupyter notebook、Atom 等上按 TAB。

即使被除数 (n+1) 是偶数,也需要整数除法才能直接得到整数结果,否则需要将结果转换为整数,这与整数除法相比成本更高。

您也可以使用右移运算符 >>或无符号右移运算符 >>> , 作为正整数除以 2^n对应于将该整数的位向右移动 n 次。尽管编译器将整数除以 2 的幂降低到位移操作,但如果被除数是有符号整数(即 Int 而不是 UInt),编译后的代码仍然会有一个额外的步骤。 因此,改用正确的位移运算符可能会提供更好的性能,尽管这可能是过早的优化并影响代码的可读性。
>>的结果和 >>>负整数将不同于整数除法( div )。

另请注意,使用无符号右移运算符 >>>可能会使您免于一些整数溢出问题。

div(x, y)

÷(x, y)

The quotient from Euclidean division. Computes x/y, truncated to an integer.


julia> 3/2 # returns a floating point number
1.5

julia> julia> 4/2
2.0

julia> 3//2 # returns a Rational
3//2  

# now integer divison
julia> div(3, 2) # returns an integer
1

julia> 3 ÷ 2 # this is the same as div(3, 2)
1

julia> 9 >> 1 # this divides a positive integer by 2
4

julia> 9 >>> 1 # this also divides a positive integer by 2
4
# results with negative numbers
julia> -5 ÷ 2
-2

julia> -5 >> 1 
-3

julia> -5 >>> 1
9223372036854775805

# results with overflowing (wrapping-around) argument
julia> (Int8(127) + Int8(3)) ÷ 2  # 127 is the largest Int8 integer 
-63

julia> (Int8(127) + Int8(3)) >> 1
-63

julia> (Int8(127) + Int8(3)) >>> 1 # still gives 65 (130 ÷ 2)
65

您可以使用 @code_native宏以查看如何将内容编译为 native 代码。请不要忘记更多的说明并不一定意味着更慢,尽管这里就是这种情况。
julia> f(a) = a ÷ 2
f (generic function with 2 methods)

julia> g(a) = a >> 1
g (generic function with 2 methods)

julia> h(a) = a >>> 1
h (generic function with 1 method)

julia> @code_native f(5)
    .text
; Function f {
; Location: REPL[61]:1
; Function div; {
; Location: REPL[61]:1
    movq    %rdi, %rax
    shrq    $63, %rax
    leaq    (%rax,%rdi), %rax
    sarq    %rax
;}
    retq
    nop
;}

julia> @code_native g(5)
    .text
; Function g {
; Location: REPL[62]:1
; Function >>; {
; Location: int.jl:448
; Function >>; {
; Location: REPL[62]:1
    sarq    %rdi
;}}
    movq    %rdi, %rax
    retq
    nopw    (%rax,%rax)
;}

julia> @code_native h(5)
    .text
; Function h {
; Location: REPL[63]:1
; Function >>>; {
; Location: int.jl:452
; Function >>>; {
; Location: REPL[63]:1
    shrq    %rdi
;}}
    movq    %rdi, %rax
    retq
    nopw    (%rax,%rax)
;}

关于julia - 使用 `Int((n+1)/2)` 、 `round(Int, (n+1)/2)` 或 `Int((n+1)//2)` 哪个更好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53465513/

相关文章:

julia - 如何在 Julia 中通过引用和值传递对象?

julia - DelimitedFiles.readdlm(source, ....) 修改源代码,这是真的吗?在文档/定义中的哪里解释了?

dataframe - 如何在 DataFrames Julia 的特定列中不区分大小写地搜索包含特殊单词大小写的行?

arrays - 如何在 Julia 中乘以多维数组/矩阵

Julia 中的 Matlab 样条函数

performance - Julia:避免由于 for 循环中的嵌套函数调用而分配内存

julia - 从 Julia 中捕获和显示输出

printf - Julia 使用 @printf 打印错误的 Pi 数字

dataframe - 当分隔符可能丢失时,如何使用 CSV.read 将文件读取到 Julia 中的 DataFrame?

types - Julia 一行中的多个类型变量