Skip to content

Instantly share code, notes, and snippets.

@sunetos
Last active August 29, 2015 14:05
Show Gist options
  • Save sunetos/f311d5408854e65d7ff9 to your computer and use it in GitHub Desktop.
Save sunetos/f311d5408854e65d7ff9 to your computer and use it in GitHub Desktop.
Julia macro to generate iterator versions of collection functions
using Devectorize
macro makeiter(func, name)
expr = quote
immutable $name{X}
x::X
end
Base.start(i::$name) = start(i.x)
Base.next(i::$name, s) = ((v, s) = next(i.x, s); ($func(v), s))
Base.done(i::$name, s) = done(i.x, s)
$name
end
return esc(expr)
end
macro iterize(oex)
if isa(oex, Symbol)
function ident(x) x end
funcname = string(func)
safename = gensym("iterate_$funcname")
iter = @eval @makeiter(ident)
return quote
function ident(x) x end
$iter($oex)
end
end
local emptyA = Int[]
ex, iters = oex, Expr[]
while ex.head == :call
func, second = ex.args[1:2]
rettype = @eval $func($emptyA)
makesarray = isa(rettype, AbstractArray)
if makesarray
funcname = string(func)
safename = gensym("iterate_$funcname")
iter = @eval @makeiter($func)
push!(iters, iter)
ex.args[1] = symbol(name)
end
!isa(second, Expr) && break || (ex = ex.args[2])
end
expr = quote
$oex
end
prepend!(expr.args, iters)
return expr
end
@makeiter abs iabs
@makeiter floor ifloor
@makeiter ceil iceil
function test()
A = randn(1<<26)
@time @devec x = sum(abs(A))
@time sum(abs(A))
@time sum(iabs(A))
@time sumabs(A)
println(sum(abs(A)))
println(sum(iabs(A)))
println(sumabs(A))
@time sum(ceil(floor(abs(A))))
@time sum(iceil(ifloor(iabs(A))))
@time @devec x = sum(ceil(floor(abs(A))))
println(sum(ceil(floor(abs(A)))))
println(sum(iceil(ifloor(iabs(A)))))
end
test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment