diff options
author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2020-05-03 14:38:19 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2020-05-03 15:29:51 +0900 |
commit | e49ecaed57181c10bf01e1f84b9eead65a759386 (patch) | |
tree | 21b48793d6c844854384734d244e4efe570a86b7 /complex.c | |
parent | 8af098b40ee3788f3d13f02298eeecfb52fa0c16 (diff) | |
download | ruby-e49ecaed57181c10bf01e1f84b9eead65a759386.tar.gz |
Optimize sin/cos
GCC/Clang can optimize to calculate `sin(x)` and `cos(x)` at once,
when the both are closely called on the same argument.
Similar optimization is possible for `__sinpi(x)` and `__cospi(x)`
if available, which calculate arguments in radian, i.e.
`sin(x*M_PI)` and `cos(x*M_PI)` respectively.
Diffstat (limited to 'complex.c')
-rw-r--r-- | complex.c | 19 |
1 files changed, 15 insertions, 4 deletions
@@ -661,8 +661,9 @@ f_complex_polar(VALUE klass, VALUE x, VALUE y) y = DBL2NUM(imag); } else { - y = f_mul(x, DBL2NUM(sin(arg))); - x = f_mul(x, DBL2NUM(cos(arg))); + const double ax = sin(arg), ay = cos(arg); + y = f_mul(x, DBL2NUM(ax)); + x = f_mul(x, DBL2NUM(ay)); if (canonicalization && f_zero_p(y)) return x; } return nucomp_s_new_internal(klass, x, y); @@ -672,6 +673,16 @@ f_complex_polar(VALUE klass, VALUE x, VALUE y) f_mul(x, m_sin(y))); } +#ifdef HAVE___COSPI +# define cospi(x) __cospi(x) +#else +# define cospi(x) cos((x) * M_PI) +#endif +#ifdef HAVE___SINPI +# define sinpi(x) __sinpi(x) +#else +# define sinpi(x) sin((x) * M_PI) +#endif /* returns a Complex or Float of ang*PI-rotated abs */ VALUE rb_dbl_complex_new_polar_pi(double abs, double ang) @@ -689,8 +700,8 @@ rb_dbl_complex_new_polar_pi(double abs, double ang) return DBL2NUM(abs); } else { - ang *= M_PI; - return rb_complex_new(DBL2NUM(abs * cos(ang)), DBL2NUM(abs * sin(ang))); + const double real = abs * cospi(ang), imag = abs * sinpi(ang); + return rb_complex_new(DBL2NUM(real), DBL2NUM(imag)); } } |