On Fri, Mar 14, 2014 at 2:03 PM, Georgios Tzanakis <gtzana...@gmail.com> wrote:
>
> On Fri, Mar 14, 2014 at 4:49 PM, Robert Bradshaw
> <rober...@math.washington.edu> wrote:
>>
>> Note that
>>
>>  <int>L[i][<int>rows[i]] + j %w == 0:
>>
>> would probably be just (or nearly) as fast as
>>
>>  ((<int>(<tuple>L[i])[<int>(rows[i])])+j %w)==0
>
>
> Good to know, thanks..
>
>>
>>
>> If you're going to be dealing with arrays of ints you might want to
>> look into NumPy
>
>
> Hmm.. I wish I knew that earlier, I deal with many of such arrays.
>
>>
>> and/or memory views for even more speed.
>
>
> Could you elaborate a bit on that? Or just give me a link?

https://www.google.com/search?q=numpy+cython

>> On Thu, Mar 13, 2014 at 7:58 PM, Georgios Tzanakis <gtzana...@gmail.com>
>> wrote:
>> > Hi Simon,
>> >
>> > I really appreciate your thorough answer! Indeed there was a bug and I
>> > had
>> > to do a couple of changes
>> > to the code, but I understood a lot of things about how to use Cython
>> > and
>> > was able to use it properly
>> > and have improvements. On top of that, I didn't know about the timeit
>> > function which is a life saver.
>> >
>> > Everything is clear.. Thank you, sir!
>> >
>> > Best,
>> > George
>> >
>> >
>> > On Thu, Mar 13, 2014 at 8:48 AM, Simon King <simon.k...@uni-jena.de>
>> > wrote:
>> >>
>> >> Hi!
>> >>
>> >> On 2014-03-12, geo909 <gtzana...@gmail.com> wrote:
>> >> > But I'm still not sure how to use things properly. So, for instance,
>> >> > is
>> >> > the
>> >> > following optimization reasonable?
>> >> > (there is an ~30% increase in speed from pure python code)
>> >>
>> >> It is easy to get more.
>> >>
>> >> But first: Is there a bug in your code?
>> >>
>> >> You write
>> >>         if all( [(L[i][rows[i]]+j %w)==0] ):
>> >> Thus, the argument to "all" is a list with precisely one item.
>> >>
>> >> If it is not a bug, then you should replace it with
>> >>        if (L[i][rows[i]]+j%w)==0:
>> >>
>> >> I assume that it is not a bug, and thus I used this improvement in all
>> >> my
>> >> attempts that I describe below.
>> >>
>> >> > # L: A list of tuples of positive integers, each having a couple of
>> >> > hundred
>> >> > elements.
>> >> > # L itself has length at most 3 or 4.
>> >> >
>> >> > # e: A tuple of integers. e has length no more than a couple of
>> >> > hundred.
>> >> > # w a small integer
>> >>
>> >> Since there is frequent access to the items of L and e, you should tell
>> >> Cython
>> >> that L is a list and that e is a tuple.
>> >>
>> >> Also, itertools.product yields tuples, so, "rows" in your function is a
>> >> tuple. Again, there is frequent acces to the items, thus, you should
>> >> declare that rows is a tuple.
>> >>
>> >> On the other hand, commonzeros is accessed at most a couple of times,
>> >> thus, no need to make it "cdef int".
>> >>
>> >> But it seems to me that the most important line is (after removing the
>> >> needless "all") this:
>> >>     if (L[i][rows[i]]+j %w)==0:
>> >>
>> >> Let's try to be particularly careful here, since it occurs in an inner
>> >> loop, and the annotation appears dark yellow.
>> >>
>> >> The items of L are tuples. Thus, one could do
>> >>    (<tuple>L[i])[rows[i]]+j
>> >> to make access to the tuple items faster.
>> >>
>> >> Furthermore, the items in the tuple L[i] are ints, and we want to add
>> >> it
>> >> with an int. Hence,
>> >>    if ((<int>(<tuple>L[i])[rows[i]])+j %w)==0:
>> >> will make it faster (actually, inserting the <int> makes the execution
>> >> time drop to 50% compared with a version that only has <tuple>).
>> >>
>> >> With
>> >>   L = [tuple([randint(1,10^8) for i in range(400)]),
>> >>     tuple([randint(1,10^8) for i in range(300)]),
>> >> tuple([randint(1,10^8)
>> >>     for i in range(500)]), tuple([randint(1,10^8) for i in
>> >> range(200)])]
>> >>   e = tuple([randint(1,10^8) for i in range(350)])
>> >>   w = 5
>> >>
>> >> and a pure Python version of your function (where I have replaced the
>> >> "all(...)" as indicated above), I get
>> >>   sage: timeit("myfunction(L,e,w)")
>> >>   5 loops, best of 3: 1.11 s per loop
>> >>
>> >> However, when cythoning your function as follows
>> >> {{{
>> >> %cython
>> >> import itertools
>> >> def myfunction(list L, tuple e, int w):
>> >>     cdef int lenL = len(L)
>> >>     cdef int i,j
>> >>     cdef tuple rows
>> >>     for rows in itertools.product(range(w), repeat=lenL):
>> >>         commonzeros=0
>> >>         for j in e:
>> >>             for i in range(lenL):
>> >>                 if ((<int>(<tuple>L[i])[<int>(rows[i])])+j %w)==0:
>> >>                     commonzeros+=1
>> >>                     if commonzeros==4:
>> >>                         return(1)
>> >>     return(0)
>> >> }}}
>> >> I get
>> >>   sage: timeit("myfunction(L,e,w)")
>> >>   5 loops, best of 3: 18.6 ms per loop
>> >>
>> >> If you now look at the annotated version of the function, you'll see
>> >> that
>> >>   for rows in itertools.product
>> >> remains dark yellow.
>> >>
>> >> So, if one wanted to optimise further, one should try to improve that.
>> >> Since you iterate over len(L) copes of range(w) (rather than over the
>> >> product of lists of different size), it should be not too difficult to
>> >> write a custom iterator in Cython.
>> >>
>> >> But perhaps the speedup (111 ms --> 18.6 ms) is good enough for you?
>> >>
>> >> Best regards,
>> >> Simon
>> >>
>> >>
>> >> --
>> >> You received this message because you are subscribed to a topic in the
>> >> Google Groups "sage-support" group.
>> >> To unsubscribe from this topic, visit
>> >> https://groups.google.com/d/topic/sage-support/S9eXmSVoo9E/unsubscribe.
>> >> To unsubscribe from this group and all its topics, send an email to
>> >> sage-support+unsubscr...@googlegroups.com.
>> >>
>> >> To post to this group, send email to sage-support@googlegroups.com.
>> >> Visit this group at http://groups.google.com/group/sage-support.
>> >> For more options, visit https://groups.google.com/d/optout.
>> >
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups
>> > "sage-support" group.
>> > To unsubscribe from this group and stop receiving emails from it, send
>> > an
>> > email to sage-support+unsubscr...@googlegroups.com.
>> > To post to this group, send email to sage-support@googlegroups.com.
>> > Visit this group at http://groups.google.com/group/sage-support.
>> > For more options, visit https://groups.google.com/d/optout.
>>
>> --
>> You received this message because you are subscribed to a topic in the
>> Google Groups "sage-support" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/d/topic/sage-support/S9eXmSVoo9E/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to
>> sage-support+unsubscr...@googlegroups.com.
>> To post to this group, send email to sage-support@googlegroups.com.
>> Visit this group at http://groups.google.com/group/sage-support.
>> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "sage-support" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sage-support+unsubscr...@googlegroups.com.
> To post to this group, send email to sage-support@googlegroups.com.
> Visit this group at http://groups.google.com/group/sage-support.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"sage-support" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-support+unsubscr...@googlegroups.com.
To post to this group, send email to sage-support@googlegroups.com.
Visit this group at http://groups.google.com/group/sage-support.
For more options, visit https://groups.google.com/d/optout.

Reply via email to