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")))) 
>>>>>> > 
>>>>>>
>>>>>>
>>>
>
>

Reply via email to