Skip to content

Commit 3103ec6

Browse files
committed
Avoid allocation for the common case
1 parent 3d68b26 commit 3103ec6

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

friture/spectrum.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
# along with Friture. If not, see <http://www.gnu.org/licenses/>.
1919

2020
from PyQt5.QtCore import QObject
21-
from numpy import log10, argmax, zeros, arange, floor, float64
21+
from numpy import log10, argmax, zeros, arange, floor, float64, ones
2222
from friture.audioproc import audioproc # audio processing class
2323
from friture.spectrum_settings import (Spectrum_Settings_Dialog, # settings dialog
2424
DEFAULT_FFT_SIZE,
@@ -105,11 +105,21 @@ def harmonic_product_spectrum(self, sp):
105105
# for pitch detection are good.
106106
product_count = 3
107107

108-
# Downsample and multiply
109108
harmonic_length = sp.shape[0] // product_count
110-
res = sp[:harmonic_length].copy()
111-
for i in range(2, product_count + 1):
112-
res *= sp[::i][:harmonic_length]
109+
110+
# common case: product_count == 3 — multiply the three slices
111+
# directly. This avoids allocating a temporary ones array and still
112+
# doesn't make copies of the original `sp` beyond NumPy's routine
113+
# temporary results for the elementwise multiplication.
114+
if product_count == 3:
115+
# Downsample and multiply
116+
res = (sp[:harmonic_length]
117+
* sp[::2][:harmonic_length]
118+
* sp[::3][:harmonic_length])
119+
else:
120+
res = ones(harmonic_length, dtype=sp.dtype)
121+
for i in range(1, product_count + 1):
122+
res *= sp[::i][:harmonic_length]
113123
return res
114124

115125
def handle_new_data(self, floatdata):

0 commit comments

Comments
 (0)