a >= b && c <= b vs !( a < b || c > b)
Что более эффективно в Джулии?
В моем случае сгенерированные коды идентичны. @code_native ((a,b,c)->a >= b && c <= b)(1,2,3)
против @code_native ((a,b,c)->!( a < b || c > b))(1,2,3)
@GKi, ты бы опубликовал это в качестве ответа?
Разница во времени выполнения, если бы она оценивала их дословно по номиналу, была бы слишком мала, чтобы ее можно было измерить. Скорее всего, он преобразует их в один и тот же исполняемый код. Я не проверял это. Такая микрооптимизация бессмысленна. Вы можете попробовать провести измерения самостоятельно и попытаться доказать, что я ошибаюсь. (если бы вы представили контрольные показатели, вы, возможно, не получили бы отрицательных голосов).
Весьма вероятно, что компилятор преобразует любое из этих выражений в ту каноническую форму, которую он сочтет наиболее удобной для вычисления для типа данных, с которым он имеет дело.
Кстати, для целых чисел a,b
я предполагаю, что выражение с использованием &&
может иметь преимущество, по крайней мере, на процессорах серии x86 из-за аппаратной поддержки инструкции TEST
, позволяющей избежать цикла записи.
Что касается ЦП, все флаги сравнения устанавливаются после операции сравнения, поэтому нет никаких штрафов за >
и <=
: условная ветвь будет выполнена или нет в зависимости от значений a
и b
.
PS В первую очередь следует стремиться к ясности и корректности. Если реализация алгоритма явно слишком медленная, тогда и только тогда используйте профилирование для поиска горячих точек. Слишком много времени тратится на преждевременную оптимизацию.
В моем случае сгенерированные коды идентичны.
@code_native ((a,b,c)->a >= b && c <= b)(1,2,3)
.text
.file "#1"
.globl "julia_#1_61" # -- Begin function julia_#1_61
.p2align 4, 0x90
.type "julia_#1_61",@function
"julia_#1_61": # @"julia_#1_61"
; ┌ @ REPL[1]:1 within `#1`
# %bb.0: # %top
push rbp
mov rbp, rsp
; │┌ @ operators.jl:425 within `>=`
; ││┌ @ int.jl:514 within `<=`
cmp rsi, rdi
setle cl
; │└└
cmp rdx, rsi
setle al
and al, cl
; │┌ @ int.jl:514 within `<=`
pop rbp
ret
.Lfunc_end0:
.size "julia_#1_61", .Lfunc_end0-"julia_#1_61"
; └└
# -- End function
.section ".note.GNU-stack","",@progbits
@code_native ((a,b,c)->!( a < b || c > b))(1,2,3)
.text
.file "#3"
.globl "julia_#3_87" # -- Begin function julia_#3_87
.p2align 4, 0x90
.type "julia_#3_87",@function
"julia_#3_87": # @"julia_#3_87"
; ┌ @ REPL[2]:1 within `#3`
# %bb.0: # %top
push rbp
mov rbp, rsp
; │┌ @ int.jl:83 within `<`
cmp rdi, rsi
setge cl
; │└
cmp rsi, rdx
setge al
and al, cl
; │┌ @ bool.jl:35 within `!`
pop rbp
ret
.Lfunc_end0:
.size "julia_#3_87", .Lfunc_end0-"julia_#3_87"
; └└
# -- End function
.section ".note.GNU-stack","",@progbits
осмотрите сборку, что вы видите? измерьте время выполнения, что вы видите?