# Julia公众号文章投稿示例

review之后, 在微信公众号里发布文章并链接我的博客.

• 引出一种优化技术: staging
• staging的例子(泛化的Fibonacci数列)
• julia中使用staging可能遇到的问题(eval, world age problem)
• julia又提供了什么办法解决以上问题(generated function)
• julia的解决方案好在哪里

@Jun 让我分享一下经验, 就是这个post. 希望能够帮到大家.

3赞

1赞

1赞

julia> foo(::Union{Val{0},Val{1}}) = 1
foo (generic function with 1 method)

julia> foo(x::Val{N}) where N = foo(Val(N-1)) + foo(Val(N-2))
foo (generic function with 2 methods)

julia> @code_typed foo(Val(20))
CodeInfo(
1 ─     return 10946
) => Int64


julia> findfirstfloat(x::Tuple, i=1) = length(x) < 1 ? nothing : first(x) isa AbstractFloat ? i : findfirstfloat(Base.tail(x), i+1)
findfirstfloat (generic function with 2 methods)

julia> findfirstfloat((1, 2, 3, 4.0, 5))
4

julia> findfirstfloat((1, 2, 3, 4, 5))

julia> @code_typed findfirstfloat((1, 2, 3, 4, 5))
CodeInfo(
1 ─     return
) => Nothing

julia> @code_typed findfirstfloat((1, 2, 3, 4.0, 5))
CodeInfo(
1 ─ %1 = Base.add_int(3, 1)::Int64
└──      return %1
) => Int64

julia> @code_llvm findfirstfloat((1, 2, 3, 4.0, 5))

;  @ REPL[1]:1 within findfirstfloat'
define i64 @julia_findfirstfloat_16075({ i64, i64, i64, double, i64 } addrspace(11)* nocapture nonnull readonly dereferenceable(40)) {
top:
ret i64 4
}


emmm，而且这么写LLVM更容易优化它啊

julia> foo(::Val{N}, x, y) where N = foo(Val(N-1), x, y) + foo(Val(N-2), x, y)
foo (generic function with 1 method)

julia> foo(::Val{0}, x, y) = x
foo (generic function with 2 methods)

julia> foo(::Val{1}, x, y) = y
foo (generic function with 3 methods)

julia> @code_llvm foo(Val(10), 1, 2)

;  @ REPL[1]:1 within foo'
define i64 @julia_foo_16107(i64, i64) {
top:
%factor = mul i64 %1, 55
%factor1 = mul i64 %0, 34
; ┌ @ int.jl:53 within +'
%2 = add i64 %factor, %factor1
; └
ret i64 %2
}


staging不是大多数时候都用不到, 只是没有相关知识发现不了. 不然oleg kiselyov也不会这么牛逼.

x0 = x + y
x1 = x0 + ...



julia> @code_lowered fibnr_staged_n(+, 0, 1, Val(10))
CodeInfo(
1 ─     $(Expr(:meta, :noinline)) │ + = f │ x0 = (+)(y, x) │ x1 = (+)(x0, y) │ x2 = (+)(x1, x0) │ x3 = (+)(x2, x1) │ x4 = (+)(x3, x2) │ x5 = (+)(x4, x3) │ x6 = (+)(x5, x4) │ x7 = (+)(x6, x5) │ x8 = (+)(x7, x6) └── return x8 ) julia> @code_lowered foo(Val(10), 0, 1) CodeInfo( 1 ─ %1 =$(Expr(:static_parameter, 1)) - 1
│   %2 = (Main.Val)(%1)
│   %3 = (Main.foo)(%2, x, y)
│   %4 = \$(Expr(:static_parameter, 1)) - 2
│   %5 = (Main.Val)(%4)
│   %6 = (Main.foo)(%5, x, y)
│   %7 = %3 + %6
└──      return %7
)


julia> fibnr_with_n_and_memo(10)
quote
function (f::Plus, x::Int64, y::Int64) where Plus <: Function
(+) = f
x0 = y + x
x1 = x0 + y
x2 = x1 + x0
x3 = x2 + x1
x4 = x3 + x2
x5 = x4 + x3
x6 = x5 + x4
x7 = x6 + x5
x8 = x7 + x6
x8
end
end
`

1赞