Skip to content

Instantly share code, notes, and snippets.

@dpo
Created April 17, 2014 17:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dpo/11000433 to your computer and use it in GitHub Desktop.
Save dpo/11000433 to your computer and use it in GitHub Desktop.
function process_types(fmt :: String, args...)
# Process types of arguments for libc's printf family.
# Grab everybody's type.
types = [typeof(arg) for arg in args]
# Perform the following conversions:
# string -> Ptr{Uint8} (for %s)
# arrays -> Ptr{Void} (for %p)
types = map(t -> (t == ASCIIString ? Ptr{Uint8} : t), types)
types = map(t -> (issubtype(t, Base.Array) ? Ptr{Void} : t), types)
types = append!([Ptr{Uint8}], types)
# ccall absolutely wants a tuple as 3rd argument.
# A variable that evaluates to a tuple just won't do.
typexpr = Expr(:tuple, types...)
return typexpr
end
function c_printf(fmt :: String, args...)
typexpr = process_types(fmt, args...)
# Ignore printf's return value (an int).
@eval ccall((:printf, "libc"), Void, $(typexpr), $(fmt), $(args...))
end
macro eval libc
1.43e-04 4.68e-02 2.09e-03
# Time some stuff.
include("cprintf.jl")
fmt = "%5d %s %8.1e %6.4f\n";
args = (12, "blablabla", pi/e, sqrt(2));
N = 1000;
# 1. @printf.
@printf("%5d %s %8.1e %6.4f\n", 12, "blablabla", pi/e, sqrt(2))
@printf("%5d %s %8.1e %6.4f\n", 12, "blablabla", pi/e, sqrt(2))
@printf("%5d %s %8.1e %6.4f\n", 12, "blablabla", pi/e, sqrt(2))
t = time();
for k = 1 : N
@printf("%5d %s %8.1e %6.4f\n", 12, "blablabla", pi/e, sqrt(2))
end;
t_printf = (time()-t)/N;
# 2. print_formatted.
print_formatted(fmt, args...) = @eval @printf($fmt, $(args...))
print_formatted(fmt, args...)
print_formatted(fmt, args...)
print_formatted(fmt, args...)
t = time();
for k = 1 : N
print_formatted(fmt, args...)
end;
t_print_formatted = (time()-t)/N;
# 3. c_printf.
c_printf(fmt, args...)
c_printf(fmt, args...)
c_printf(fmt, args...)
t = time();
for k = 1 : N
c_printf(fmt, args...)
end;
t_c_printf = (time()-t)/N;
print_formatted("%8s %8s %8s\n", "macro", "eval", "libc")
print_formatted("%8.2e %8.2e %8.2e\n", t_printf, t_print_formatted, t_c_printf);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment