[Cs254f11] More performance issues with a particular function

Wm. Josiah Erikson wjerikson at hampshire.edu
Wed Nov 16 21:03:54 EST 2011


mod must take a long time, because I thought about how to reduce the 
number of them on the way home, came up with this:

(defn is_it_a_member
   "Takes number and a collection, returns 1 if number is in the 
collection, 0 if it isn't"
   [num coll]
   (count (filter #(= (mod num 12) %) coll)))

(defn percent_in_mixolydian
   "Returns the percentage of real notes in the current song that are in 
the mixolydian scale,
    assuming that the most common note is the root"
   []
   (let [modded-scale (map #(mod (+ (most_common_real_note) %) 12) 
(:mixolydian scales))]
       (int( *( / (reduce + (map #(is_it_a_member % modded-scale) 
(get_real_notes (get_note_lines song))))
         (number_of_real_notes)) 100))))

And now:

(time (percent_in_mixolydian))
"Elapsed time: 251.489 msecs"
51

A bit more acceptable!

     -Josiah


On 11/16/11 7:28 PM, Wm. Josiah Erikson wrote:
> Hey guys,
>     So I'm having a very serious performance issue with a particular 
> function that I'm writing to find out what percentage of the notes in 
> a given song are in a given scale.
>
> So first, the relevant info to understand what I'm doing:
>
> ;Define some scales, relative
> (def scales {
>              :mixolydian '(0 2 4 5 7 9 10)
>              :lydian '(0 2 4 5 7 9 11)
>              :major '(0 2 4 5 7 9 11)
>              :pentatonic '(0 3 5 7 10)
>              :blues '(0 3 4 5 6 7 10)
>              })
>
> (defn score-against-scale
>   "Compares the given note against scale (which should be a list of 
> values) and key and returns 1 if it is in the scale, 0 if not"
>   [note scale key]
>   (count(filter #(= (mod note 12) (mod (+ %1 key) 12)) scale)))
>
> ;Then this takes forever:
>
> (defn percent_in_mixolydian
>   "Returns the percentage of real notes in the current song that are 
> in the mixolydian scale,
>    assuming that the most common note is the root"
>   []
>   (/
>     (reduce + (map #(score-against-scale % (:mixolydian scales) (mod 
> (most_common_real_note) 12))
>        (get_real_notes (get_note_lines song))))
>   (number_of_real_notes)))
>
>
> Now, I've done a bunch of troubleshooting, and (most_common_real_note) 
> returns quickly, as does (number_of_real_notes), and both of those 
> functions actually also call (get_real_notes (get_note_lines song)), 
> so that's not the issue - it's the
>
> (map #(score-against-scale % (:mixolydian scales) (mod 
> (most_common_real_note) 12))
>        (get_real_notes (get_note_lines song)))
>
> that takes forever. This returns immediately, since it creates a lazy 
> sequence:
>
> (def a (map #(score-against-scale % (:mixolydian scales) (mod 
> (most_common_real_note) 12))
>        (get_real_notes (get_note_lines song))))
>
> But then if I do:
>
> (def b (vec a))
>
> To make it un-lazy, it never returns, or rather, it takes so long that 
> I haven't let it return yet.
>
> (count a)
>
> Also takes forever, I suppose for the same reason. Some math:
>
> (time (score-against-scale 4 (:mixolydian scales) (mod 
> (most_common_real_note) 12)))
> "Elapsed time: 26.771 msecs"
>
> (number_of_real_notes)
> 12166
>
> (/ (* 0.026 12166) 60)
> 5.271933333333333
>
> Humph. So it will take 5.2 minutes just to run through my song and 
> compare each note to the mixolydian scale? What am I doing wrong?
>
> Thanks for any suggestions,
> -Josiah
>
>
> _______________________________________________
> Cs254f11 mailing list
> Cs254f11 at lists.hampshire.edu
> https://lists.hampshire.edu/mailman/listinfo/cs254f11


More information about the Cs254f11 mailing list