From 42abad2464a78e3ec8a42f85c7bc878233f3ce16 Mon Sep 17 00:00:00 2001 From: Yusuke Endoh Date: Tue, 12 May 2020 02:12:06 +0900 Subject: [PATCH] numeric.c: optimize `float ** 2` case by fastpath It would be a relatively frequent case. It is still slower than `float * float` because `*` has a dedicated VM instruction (opt_mult), though. --- numeric.c | 6 +++++- test/ruby/test_float.rb | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/numeric.c b/numeric.c index 03d8b86a1d..04fd3a24af 100644 --- a/numeric.c +++ b/numeric.c @@ -1309,7 +1309,11 @@ VALUE rb_float_pow(VALUE x, VALUE y) { double dx, dy; - if (RB_TYPE_P(y, T_FIXNUM)) { + if (y == INT2FIX(2)) { + dx = RFLOAT_VALUE(x); + return DBL2NUM(dx * dx); + } + else if (RB_TYPE_P(y, T_FIXNUM)) { dx = RFLOAT_VALUE(x); dy = (double)FIX2LONG(y); } diff --git a/test/ruby/test_float.rb b/test/ruby/test_float.rb index 0daa3cca57..fbf0d87f8e 100644 --- a/test/ruby/test_float.rb +++ b/test/ruby/test_float.rb @@ -305,6 +305,7 @@ class TestFloat < Test::Unit::TestCase assert_equal(1.0, 1.0 ** (2**32)) assert_equal(1.0, 1.0 ** 1.0) assert_raise(TypeError) { 1.0 ** nil } + assert_equal(9.0, 3.0 ** 2) end def test_eql