[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