-
-
Notifications
You must be signed in to change notification settings - Fork 49
Open
Description
This is a good benchmark of how well higher-order programming can be optimized, which is something we're actually notably missing in Julia. A basic implementation in Julia was given here:
function argmax(f, itr)
r = iterate(itr)
r === nothing && error("empty collection")
m, state = r
f_m = f(m)
while true
r = iterate(itr, state)
r === nothing && break
x, state = r
f_x = f(x)
isless(f_m, f_x) || continue
m, f_m = x, f_x
end
return m
end
The really neat part is how tight the resulting machine code can be for a simple user-defined function based on this generic higher-order argmax
defintion, e.g.:
rangemax(f, a, b) = argmax(f, min(a,b):max(a,b))
the native code for a call like rangemax(x -> -abs(x-3), -10, 10)
is quite efficient:
cmpq %rdi, %rsi
movq %rdi, %r8
cmovleq %rsi, %r8
cmovlq %rdi, %rsi
cmpq %rsi, %r8
jne L23
movq %r8, %rax
retq
L23:
leaq -3(%r8), %rax
movl $3, %ecx
subq %r8, %rcx
testq %rax, %rax
cmovnsq %rax, %rcx
negq %rcx
movq %r8, %rax
L48:
movl $2, %edi
subq %r8, %rdi
leaq -2(%r8), %r9
leaq 1(%r8), %rdx
testq %r9, %r9
cmovnsq %r9, %rdi
negq %rdi
cmpq %rdi, %rcx
cmovlq %rdx, %rax
cmovlq %rdi, %rcx
movq %rdx, %r8
cmpq %rsi, %rdx
jne L48
retq
This is a case where C may actually have a fairly hard time and C++ will do better using templates. Rust seems like it would do well at this too; most other languages will get killed on this one.
Metadata
Metadata
Assignees
Labels
No labels