[Cs254f11] More performance issues with a particular function
Wm. Josiah Erikson
wjerikson at hampshire.edu
Wed Nov 16 19:28:06 EST 2011
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
More information about the Cs254f11
mailing list