-
-
Notifications
You must be signed in to change notification settings - Fork 18.6k
Performance increase rolling min max #19549
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 16 commits
737c033
15d2563
06f2658
8089e67
08ff553
6ef87b2
6e8c041
b0a0ef6
b19774e
92857ee
832ff9d
f00e994
0d713be
1ab4e21
d5b60cd
42f8fdf
38e3f70
7f4abf9
23fe816
060dfb7
aeb9b9b
65c0dbe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#ifndef _PANDAS_MATH_H_ | ||
#define _PANDAS_MATH_H_ | ||
|
||
#if defined(_MSC_VER) && (_MSC_VER < 1800) | ||
#include <cmath> | ||
namespace std { | ||
__inline int signbit(double num) { return _copysign(1.0, num) < 0; } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would revert this to use math.h - technically extending namespace There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think that's the right direction to go, cmath is what you use when you write C++ code. math.h doesn't work either when compiling in clang. This works in all three compilers even though it's not the most ideal (MSVC doesn't have this defined for older versions which is annoying). |
||
} | ||
#else | ||
#include <cmath> | ||
#endif | ||
|
||
#endif |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
|
||
cimport cython | ||
from cython cimport Py_ssize_t | ||
from libcpp.deque cimport deque | ||
|
||
from libc.stdlib cimport malloc, free | ||
|
||
|
@@ -12,7 +13,7 @@ from numpy cimport ndarray, double_t, int64_t, float64_t | |
cnp.import_array() | ||
|
||
|
||
cdef extern from "../src/headers/math.h": | ||
cdef extern from "../src/headers/cmath" namespace "std": | ||
int signbit(double) nogil | ||
double sqrt(double x) nogil | ||
|
||
|
@@ -1222,8 +1223,9 @@ cdef _roll_min_max(ndarray[numeric] input, int64_t win, int64_t minp, | |
cdef: | ||
numeric ai | ||
bint is_variable, should_replace | ||
int64_t s, e, N, i, j, removed | ||
int64_t N, i, removed, window_i | ||
Py_ssize_t nobs = 0 | ||
deque Q[int64_t] | ||
ndarray[int64_t] starti, endi | ||
ndarray[numeric, ndim=1] output | ||
cdef: | ||
|
@@ -1242,32 +1244,43 @@ cdef _roll_min_max(ndarray[numeric] input, int64_t win, int64_t minp, | |
|
||
output = np.empty(N, dtype=input.dtype) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you add a description of the algorithm and a link (if available) |
||
Q = deque[int64_t]() | ||
|
||
if is_variable: | ||
|
||
with nogil: | ||
|
||
for i in range(N): | ||
s = starti[i] | ||
e = endi[i] | ||
for i from starti[0] <= i < endi[0]: | ||
ai = init_mm(input[i], &nobs, is_max) | ||
|
||
r = input[s] | ||
nobs = 0 | ||
for j in range(s, e): | ||
if is_max: | ||
while not Q.empty() and ai >= input[Q.back()]: | ||
Q.pop_back() | ||
else: | ||
while not Q.empty() and ai <= input[Q.back()]: | ||
Q.pop_back() | ||
Q.push_back(i) | ||
|
||
# adds, death at the i offset | ||
ai = init_mm(input[j], &nobs, is_max) | ||
for i from endi[0] <= i < N: | ||
output[i-1] = calc_mm(minp, nobs, input[Q.front()]) | ||
|
||
if is_max: | ||
if ai > r: | ||
r = ai | ||
else: | ||
if ai < r: | ||
r = ai | ||
ai = init_mm(input[i], &nobs, is_max) | ||
|
||
output[i] = calc_mm(minp, nobs, r) | ||
if is_max: | ||
while not Q.empty() and ai >= input[Q.back()]: | ||
Q.pop_back() | ||
else: | ||
while not Q.empty() and ai <= input[Q.back()]: | ||
Q.pop_back() | ||
|
||
else: | ||
while not Q.empty() and Q.front() <= i - (endi[i] - starti[i]): | ||
Q.pop_front() | ||
|
||
Q.push_back(i) | ||
|
||
output[N-1] = calc_mm(minp, nobs, input[Q.front()]) | ||
|
||
else: | ||
# setup the rings of death! | ||
ring = <numeric *>malloc(win * sizeof(numeric)) | ||
death = <int64_t *>malloc(win * sizeof(int64_t)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add commets here on why we have this file (so the next person doesn't go thru the same as you :>)