Here are some timings comparing @printf with the proposed @eval option. I also wanted to try a variant that calls libc's printf directly. I came up with this implementation: https://gist.github.com/11000433. Its "advantage" is that you can print an array's address using %p (for what it's worth).
I didn't find a way around another @eval due to what ccall expects its arguments to look like. I thought it would be easy to call libc's printf, but it wasn't! (Also I'm sure cprintf should be more sophisticated than it currently is, but for now, it does what I need.) Running time_printf.jl on my Macbook pro gives the following timings: macro eval libc 8.06e-05 5.91e-02 6.63e-03 These are averages over 1000 calls. The call to libc's printf isn't doing too badly compared to the simpler @eval proposed by Stefan. But I'm wondering if it's possible to avoid the @eval in cprintf and call the C function directly?! Are there other options? I'm all for performance but when it comes to printing, convenience and flexibility are also a must in my opinion. Because printing is inherently inefficient, I'm willing to accept performance hits there. Many thanks for all the help. ps: Shoudln't @time return the execution time? On Thursday, April 17, 2014 9:17:59 AM UTC-7, John Myles White wrote: > > I think the question is how to time a proposed sprintf() function vs. the > existing @sprintf macro. > > -- John > > On Apr 17, 2014, at 7:27 AM, Stefan Karpinski > <[email protected]<javascript:>> > wrote: > > I'm not sure what you mean, but doing things in a loop and timing it is > the normal way. The lack of usefulness of my answer may be indicative that > I don't understand the question. > > > On Wed, Apr 16, 2014 at 11:13 PM, Dominique Orban > <[email protected]<javascript:> > > wrote: > >> How would one go about benchmarking a set of implementations like those? >> >> >> On Sunday, April 13, 2014 3:22:58 PM UTC-7, Stefan Karpinski wrote: >> >>> Please don't do this – or if you do and your program is amazingly slow, >>> then consider yourself warned. You can define a custom formatting function >>> pretty easily: >>> >>> julia> fmt = "%8.1e" >>> "%8.1e" >>> >>> julia> @eval dofmt(x) = @sprintf($fmt, x) >>> dofmt (generic function with 1 method) >>> >>> julia> dofmt(1) >>> " 1.0e+00" >>> >>> julia> dofmt(123.456) >>> " 1.2e+02" >>> >>> >>> The difference is that you compile the function definition with eval >>> *once* and then call it many times, rather than calling eval every time you >>> want to print something. >>> >>> >>> On Sun, Apr 13, 2014 at 6:17 PM, Mike Innes <[email protected]> wrote: >>> >>>> It occurs to me that, if you really need this, you can define >>>> >>>> sprintf(args...) = eval(:@sprintf($(args...))) >>>> >>>> It's not pretty or ideal in terms of performance, but it will do the >>>> job. >>>> >>>> fmt = "%8.1e" >>>> sprintf(fmt, 3.141) #=> " 3.1e+00" >>>> >>>> On Sunday, 13 April 2014 22:47:12 UTC+1, Dominique Orban wrote: >>>>> >>>>> So what's the preferred Julia syntax to achieve what I meant here: >>>>> >>>>> julia> fmt = "%8.1e"; >>>>> julia> @sprintf(fmt, 3.1415) >>>>> ERROR: first or second argument must be a format string >>>>> >>>>> >>>>> >>>>> On Sunday, April 13, 2014 1:31:57 PM UTC-7, John Myles White wrote: >>>>>> >>>>>> As far as the macro is concerned, the splat isn’t executed: it’s just >>>>>> additional syntax that gets taken in as a whole expression. >>>>>> >>>>>> The contrast between how a function with splatting works and how a >>>>>> macro with splatting works might be helpful: >>>>>> >>>>>> julia> function splat(a, b...) >>>>>> println(a) >>>>>> println(b) >>>>>> return >>>>>> end >>>>>> splat (generic function with 2 methods) >>>>>> >>>>>> julia> splat(1, 2, 3) >>>>>> 1 >>>>>> (2,3) >>>>>> >>>>>> julia> splat(1, [2, 3]...) >>>>>> 1 >>>>>> (2,3) >>>>>> >>>>>> julia> macro splat(a, b...) >>>>>> println(a) >>>>>> println(b) >>>>>> :() >>>>>> end >>>>>> >>>>>> julia> @splat(1, 2, 3) >>>>>> 1 >>>>>> (2,3) >>>>>> () >>>>>> >>>>>> julia> @splat(1, [2, 3]...) >>>>>> 1 >>>>>> (:([2,3]...),) >>>>>> () >>>>>> >>>>>> >>>>>> — John >>>>>> >>>>>> On Apr 13, 2014, at 1:20 PM, Jeff Waller <[email protected]> wrote: >>>>>> >>>>>> > Likewise I am having problems with @sprintf >>>>>> > >>>>>> > Is this because @sprinf is macro? The shorthand of expanding a >>>>>> printf with format the contents of an array is desirable. I would have >>>>>> expected the ... operator to take an array of length 2 and turn it into >>>>>> 2 >>>>>> arguments. >>>>>> > >>>>>> > julia> X=[1 2] >>>>>> > 1x2 Array{Int64,2}: >>>>>> > 1 2 >>>>>> > >>>>>> > julia> @sprintf("%d%d",1,2) >>>>>> > "12" >>>>>> > >>>>>> > julia> @sprintf("%d%d",X...) >>>>>> > ERROR: @sprintf: wrong number of arguments >>>>>> > >>>>>> > julia> @sprintf("%d%d",(1,2)...) >>>>>> > ERROR: @sprintf: wrong number of arguments >>>>>> > >>>>>> > julia> @sprintf("%d",X...) >>>>>> > ERROR: error compiling anonymous: unsupported or misplaced >>>>>> expression ... in function anonymous >>>>>> > in sprint at io.jl:460 >>>>>> > in sprint at io.jl:464 >>>>>> > >>>>>> > julia> macroexpand(quote @sprintf("%d%d",X...) end) >>>>>> > :($(Expr(:error, ErrorException("@sprintf: wrong number of >>>>>> arguments")))) >>>>>> > >>>>>> >>>>>> >>> > >
