[julia-users] Re: some Python / Julia comparisons

2014-09-20 Thread stonebig34
Hi Jason,

Could it be possible for you to create a Julia program to compare it with 
the famous Jake Vanderplas post ?
http://jakevdp.github.io/blog/2013/06/15/numba-vs-cython-take-2/

Under which type of problem Julia fly much higher or easily than 
cython/pypy/numba ?
("much" = x3 in my mind)

Le samedi 20 septembre 2014 18:41:02 UTC+2, Jason Trenouth a écrit :
>
> Hi,
>
> I converted some Python programs to Julia recently. The (probably 
> incorrect) ramblings are here:
>
> http://a-coda.tumblr.com/post/93907978846/julia-dream
>
> http://a-coda.tumblr.com/post/97973293291/a-recurring-dream
>
> tl;dr - similar in style, but Julia can be a lot faster
>
> __Jason
>
>

[julia-users] Re: some Python / Julia comparisons

2014-09-20 Thread Jason Merrill
One thing that's really nice about Julia is that it's often straightforward 
to transliterate python code (or matlab code) in a fairly literal way and 
end up with working code that has similar, or sometimes better performance.

But another nice thing about Julia is that it allows you to fairly smoothly 
move from python or matlab-like code to c-like code that has much better 
performance, in the places where this matters. There's usually some work to 
do to achieve this, though. I.e. you can't generally expect that 
inefficiently vectorized matlab-style code, or python-style code that uses 
tons of Dict lookups, will perform orders of magnitude better in Julia than 
it did in the original languages.

To put it differently, "Julia makes code run fast" is too simplistic, but 
"Julia lets me write expressive high level code," "Julia lets me write 
performant low level code", and "Julia lets me smoothly move back and forth 
between high level code and low level code" are all true in my experience.

Okay, so finally the reason for this sermon: if you want to, I think you 
could wring a lot more performance out of that Viterbi code. I haven't 
actually tried this yet, but I think you could replace a lot of your data 
structures with arrays and vectors of floats and ints, and then you'll 
probably see performance improvements like 2x or 10x or 100x instead of 
1.26x.

If you treat your states, ["Healthy", "Fever"], and your observations 
["normal", "cold", "dizzy"] like enums, i.e. think of those strings mapping 
onto integers, then your start probability can become a vector of 2 floats, 
your transition probability is a 2x2 float array, and your emission 
probability is a 2x3 float array.

The big improvement will come from treating "paths" as an int array. Right 
now, it's a Dict{K,Any}(), and you allocate a new dict on each iteration, 
which is probably really hurting you. You could translate it to a Nx2 
array, where N is the number of observations, and 2 is the number of 
states, and then allocate it all at the beginning. At each step n, you then 
fill in the nth row with integers that tell you which column to look in 
above you to keep following the path backwards.

If you try any of this, I'd love to know how it goes. If you're after 
performance here, I suspect you'll be impressed by the results.

Best,

Jason

On Saturday, September 20, 2014 9:41:02 AM UTC-7, Jason Trenouth wrote:
>
> Hi,
>
> I converted some Python programs to Julia recently. The (probably 
> incorrect) ramblings are here:
>
> http://a-coda.tumblr.com/post/93907978846/julia-dream
>
> http://a-coda.tumblr.com/post/97973293291/a-recurring-dream
>
> tl;dr - similar in style, but Julia can be a lot faster
>
> __Jason
>
>

[julia-users] Re: some Python / Julia comparisons

2014-09-21 Thread Jason Merrill
I got curious, and ended up implementing this myself:

https://gist.github.com/jwmerrill/ff422bf00593e006c1a4

On my laptop, your Viterbi benchmark runs in 6.9s, and this new 
implementation runs in 0.5s, so it's something like 14x faster. If you 
wanted to push on performance any more, I'd recommend moving to a longer 
set of observations, and checking how execution time scales with

1. The number of observations
2. The size of the state space
3. The size of the observation space

You can end up optimizing the wrong things if you only benchmark a toy 
example that executes in half a microsecond.

If you do move to a longer set of observations, you might want to switch to 
storing and manipulating log probabilities instead of probabilities to 
avoid underflow. It looks like this algorithm only ever multiplies 
probabilities (never adds them), which is convenient because in log space, 
multiplication is translated to addition, but addition is translated to 
something that requires taking exponents and logs.

A couple of additional comments:

1. Note the lack of type annotations on the viterbi function. They aren't 
necessary for performance, as long as the input is well typed. Sometimes 
they can be useful for documentation or error checking though.

2. I made the problem data const. It occurs in global scope, so this is 
necessary to make sure that it is precisely typed.

3. Most of the time is now spent allocating V, maxindices, and the output 
of path, and also inside first_index. I checked this by running

@profile benchmark_example(10)
Profile.print()

Only the most recent column of V is ever used, so you could probably speed 
things up by only storing 1 column of V, and mutating it. first_index could 
probably be further optimized by dispatching on the length of the string or 
its first char or something like that, but I decided not to mess with that.

On Saturday, September 20, 2014 11:43:11 AM UTC-7, Jason Merrill wrote:
>
> One thing that's really nice about Julia is that it's often 
> straightforward to transliterate python code (or matlab code) in a fairly 
> literal way and end up with working code that has similar, or sometimes 
> better performance.
>
> But another nice thing about Julia is that it allows you to fairly 
> smoothly move from python or matlab-like code to c-like code that has much 
> better performance, in the places where this matters. There's usually some 
> work to do to achieve this, though. I.e. you can't generally expect that 
> inefficiently vectorized matlab-style code, or python-style code that uses 
> tons of Dict lookups, will perform orders of magnitude better in Julia than 
> it did in the original languages.
>
> To put it differently, "Julia makes code run fast" is too simplistic, but 
> "Julia lets me write expressive high level code," "Julia lets me write 
> performant low level code", and "Julia lets me smoothly move back and forth 
> between high level code and low level code" are all true in my experience.
>
> Okay, so finally the reason for this sermon: if you want to, I think you 
> could wring a lot more performance out of that Viterbi code. I haven't 
> actually tried this yet, but I think you could replace a lot of your data 
> structures with arrays and vectors of floats and ints, and then you'll 
> probably see performance improvements like 2x or 10x or 100x instead of 
> 1.26x.
>
> If you treat your states, ["Healthy", "Fever"], and your observations 
> ["normal", "cold", "dizzy"] like enums, i.e. think of those strings mapping 
> onto integers, then your start probability can become a vector of 2 floats, 
> your transition probability is a 2x2 float array, and your emission 
> probability is a 2x3 float array.
>
> The big improvement will come from treating "paths" as an int array. Right 
> now, it's a Dict{K,Any}(), and you allocate a new dict on each iteration, 
> which is probably really hurting you. You could translate it to a Nx2 
> array, where N is the number of observations, and 2 is the number of 
> states, and then allocate it all at the beginning. At each step n, you then 
> fill in the nth row with integers that tell you which column to look in 
> above you to keep following the path backwards.
>
> If you try any of this, I'd love to know how it goes. If you're after 
> performance here, I suspect you'll be impressed by the results.
>
> Best,
>
> Jason
>
> On Saturday, September 20, 2014 9:41:02 AM UTC-7, Jason Trenouth wrote:
>>
>> Hi,
>>
>> I converted some Python programs to Julia recently. The (probably 
>> incorrect) ramblings are here:
>>
>> http://a-coda.tumblr.com/post/93907978846/julia-dream
>>
>> http://a-coda.tumblr.com/post/97973293291/a-recurring-dream
>>
>> tl;dr - similar in style, but Julia can be a lot faster
>>
>> __Jason
>>
>>

[julia-users] Re: some Python / Julia comparisons

2014-09-21 Thread Jason Trenouth
On Sunday, 21 September 2014 19:23:20 UTC+1, Jason Merrill wrote:
>
> I got curious, and ended up implementing this myself:
>
 
Hi Jason,

Thanks for this and your previous comment. 

I might play about with this some more myself, e.g. back translate to 
Python to compare again.

Note that the original Python code was just taken from the Wikipedia page 
on Viterbi and was probably only meant for educational purposes.

I was trying to see how little I could change the code to speed things up 
while showing off some aspects of Julia.

__Jason



[julia-users] Re: some Python / Julia comparisons

2014-09-21 Thread Jason Trenouth


On Saturday, 20 September 2014 18:45:31 UTC+1, stone...@gmail.com wrote:
>
> Hi Jason,
>
> Could it be possible for you to create a Julia program to compare it with 
> the famous Jake Vanderplas post ?
> http://jakevdp.github.io/blog/2013/06/15/numba-vs-cython-take-2/
>
> Under which type of problem Julia fly much higher or easily than 
> cython/pypy/numba ?
> ("much" = x3 in my mind)
>
>
Hi,

As a Julia newbie I'm not sure I'm the right person to ask to do such a 
bake-off, but there may be others who'll bite.

__Jason



[julia-users] Re: some Python / Julia comparisons

2014-09-21 Thread Jason Merrill
On Sunday, September 21, 2014 12:21:37 PM UTC-7, Jason Trenouth wrote:
>
> On Sunday, 21 September 2014 19:23:20 UTC+1, Jason Merrill wrote:
>>
>> I got curious, and ended up implementing this myself:
>>
>  
> I was trying to see how little I could change the code to speed things up 
> while showing off some aspects of Julia.
>

Yeah, totally, and I think that's valuable. It's nice to know that "you, 
yes you! can probably port your python code to Julia and get it working 
today."

But I'm advocating that you're missing a lot of the benefit (and a lot of 
the fun!) if you don't then massage your code to take advantage of Julia's 
strengths.

If I read your post without knowing anything about Julia, I think I might 
conclude "oh, great, Julia is another language that's good for writing 
recursive factorial, but the performance improvements aren't so impressive 
for real algorithms like Viterbi." I wouldn't bother porting my code to a 
whole different language for a 26% performance improvement, unless maybe I 
was trying to get a few more fps in a game or something like that.


[julia-users] Re: some Python / Julia comparisons

2014-09-21 Thread Jason Merrill
On Saturday, September 20, 2014 10:45:31 AM UTC-7, stone...@gmail.com wrote:
>
> Hi Jason,
>
> Could it be possible for you to create a Julia program to compare it with 
> the famous Jake Vanderplas post ?
> http://jakevdp.github.io/blog/2013/06/15/numba-vs-cython-take-2/
>
> Under which type of problem Julia fly much higher or easily than 
> cython/pypy/numba ?
> ("much" = x3 in my mind)
>

You should just try it. `pairwise_python` from that post can be translated 
to Julia quite literally. I didn't succeed in installing numba in my first 
5 minutes of trying, so I can't really report on comparative performance, 
but I can tell you that the Julia version's execution time is measured in 
ms, and the pure python version's execution time is measured in seconds.

BTW, I think in Julia it might be better to represent the points as a 
3x1000 array instead of a 1000x3 array, since you want the point 
coordinates to be stored next to each other in memory for this algorithm.

See also "pairwise" from the Distances.jl package.


[julia-users] Re: some Python / Julia comparisons

2014-09-21 Thread Hans W Borchers
Python w/ numba and Julia are comparable in speed for the tests I did. This 
is 
not surprising as numba utilizes LLVM as well. For the above example and on 
my 
Unix computer, the timings are 15 ms for Python+numba and 20 ms for Julia.

If one gets the data as 1000x3 matrix, should one really first transpose 
the 
matrix and then apply a distance function on 3x1000? I don't think so.


On Sunday, September 21, 2014 10:52:43 PM UTC+2, Jason Merrill wrote:
>
> On Saturday, September 20, 2014 10:45:31 AM UTC-7, stone...@gmail.com 
> wrote:
>>
>> Hi Jason,
>>
>> Could it be possible for you to create a Julia program to compare it with 
>> the famous Jake Vanderplas post ?
>> http://jakevdp.github.io/blog/2013/06/15/numba-vs-cython-take-2/
>>
>> Under which type of problem Julia fly much higher or easily than 
>> cython/pypy/numba ?
>> ("much" = x3 in my mind)
>>
>
> You should just try it. `pairwise_python` from that post can be translated 
> to Julia quite literally. I didn't succeed in installing numba in my first 
> 5 minutes of trying, so I can't really report on comparative performance, 
> but I can tell you that the Julia version's execution time is measured in 
> ms, and the pure python version's execution time is measured in seconds.
>
> BTW, I think in Julia it might be better to represent the points as a 
> 3x1000 array instead of a 1000x3 array, since you want the point 
> coordinates to be stored next to each other in memory for this algorithm.
>
> See also "pairwise" from the Distances.jl package.
>


[julia-users] Re: some Python / Julia comparisons

2014-09-22 Thread Mohammed El-Beltagy
Examining your Viterbi Julia implementation, I noticed that you expand that 
path by 
newpath[y] = ( y, path[state] )
This would result in nested tuples. However in python with 
newpath[y] = path[state] + [y]
you get a nice flat tuple. 

You can modify the Julia code to get a comparable path tuple by :
newpath[y] = tuple( y, path[state]... )
However, that slowed down things by 55% on my machine. 

Without drastic modification to the code's structure, the following line 
were modified 
path = Dict{K,Array{K,1}}() # Made the type even more explicit in path 
declaration
path[y] = [y] # Array, not tuple in the base case
#=newpath = Dict{K,Any}()=# Comment this line out 
push!(path[state],y) # instead of newpath
#=path = newpath=# Comment out this line also 

By cutting down on unnecessary memory allocation, the code with the above 
modifications runs 21% faster than your original Julia implementation. In 
some ways it is also cleaner and more concise. 







On Saturday, September 20, 2014 7:41:02 PM UTC+3, Jason Trenouth wrote:
>
> Hi,
>
> I converted some Python programs to Julia recently. The (probably 
> incorrect) ramblings are here:
>
> http://a-coda.tumblr.com/post/93907978846/julia-dream
>
> http://a-coda.tumblr.com/post/97973293291/a-recurring-dream
>
> tl;dr - similar in style, but Julia can be a lot faster
>
> __Jason
>
>

[julia-users] Re: some Python / Julia comparisons

2014-09-22 Thread Mohammed El-Beltagy
Sorry, just realized the my last modifications were logically incorrect. 
Having the newpath variable is essential. 

On Monday, September 22, 2014 12:09:34 PM UTC+3, Mohammed El-Beltagy wrote:
>
> Examining your Viterbi Julia implementation, I noticed that you expand 
> that path by 
> newpath[y] = ( y, path[state] )
> This would result in nested tuples. However in python with 
> newpath[y] = path[state] + [y]
> you get a nice flat tuple. 
>
> You can modify the Julia code to get a comparable path tuple by :
> newpath[y] = tuple( y, path[state]... )
> However, that slowed down things by 55% on my machine. 
>
> Without drastic modification to the code's structure, the following line 
> were modified 
> path = Dict{K,Array{K,1}}() # Made the type even more explicit in path 
> declaration
> path[y] = [y] # Array, not tuple in the base case
> #=newpath = Dict{K,Any}()=# Comment this line out 
> push!(path[state],y) # instead of newpath
> #=path = newpath=# Comment out this line also 
>
> By cutting down on unnecessary memory allocation, the code with the above 
> modifications runs 21% faster than your original Julia implementation. In 
> some ways it is also cleaner and more concise. 
>
>
>
>
>
>
>
> On Saturday, September 20, 2014 7:41:02 PM UTC+3, Jason Trenouth wrote:
>>
>> Hi,
>>
>> I converted some Python programs to Julia recently. The (probably 
>> incorrect) ramblings are here:
>>
>> http://a-coda.tumblr.com/post/93907978846/julia-dream
>>
>> http://a-coda.tumblr.com/post/97973293291/a-recurring-dream
>>
>> tl;dr - similar in style, but Julia can be a lot faster
>>
>> __Jason
>>
>>

Re: [julia-users] Re: some Python / Julia comparisons

2014-09-21 Thread Tim Holy
On Sunday, September 21, 2014 03:02:38 PM Hans W Borchers wrote:
> If one gets the data as 1000x3 matrix, should one really first transpose
> the
> matrix and then apply a distance function on 3x1000? I don't think so.

It depends on the coming algorithm. 1000 points is not very much; the whole 
thing would fit into L1 cache, and so for 1000 points there's no incentive. But 
change that to 10^5 points, so the total computational cost is 10^10, and you 
could get an 5-10 fold speedup even with the cost of that transposition. When 
it comes to performance, cache is a huge consideration, and an O(N) reordering 
is totally worth it for an O(N^2) algorithm.

Of course, if you're using the Euclidean distance, you can do it using BLAS 
matrix multiplication (with some loss in precision), and BLAS already worries 
about cache for you. So in that particular case, with that particular 
algorithm, it wouldn't be necessary. But basically any other metric (or if you 
are worried about that loss of precision and want to use the higher-precision 
"naive" algorithm), you'll want the points arranged along columns.

--Tim