ruby-dev (Japanese) list archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-dev:50716] [Ruby trunk Bug#15435] Float の Infinity ni
       [not found] <redmine.issue-15435.20181219080858@ruby-lang.org>
@ 2018-12-19  8:08 ` shuujii
  2018-12-19  8:13 ` [ruby-dev:50717] [Ruby trunk Bug#15435] Float の Infinity shuujii
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 6+ messages in thread
From: shuujii @ 2018-12-19  8:08 UTC (permalink / raw)
  To: ruby-dev

Issue #15435 has been reported by shuujii (Shuji KOBAYASHI).

----------------------------------------
Bug #15435: Float の Infinity ni
https://bugs.ruby-lang.org/issues/15435

* Author: shuujii (Shuji KOBAYASHI)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.6.0rc2 (2018-12-15 trunk 66408) [x86_64-linux]
* Backport: 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------




-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-dev:50717] [Ruby trunk Bug#15435] Float の Infinity ...
       [not found] <redmine.issue-15435.20181219080858@ruby-lang.org>
  2018-12-19  8:08 ` [ruby-dev:50716] [Ruby trunk Bug#15435] Float の Infinity ni shuujii
@ 2018-12-19  8:13 ` shuujii
  2018-12-19  8:54 ` [ruby-dev:50718] [Ruby trunk Feature#15435] Float の Infinity に生成済みの値を使用する shuujii
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 6+ messages in thread
From: shuujii @ 2018-12-19  8:13 UTC (permalink / raw)
  To: ruby-dev

Issue #15435 has been updated by shuujii (Shuji KOBAYASHI).

Subject changed from Float の Infinity ni to Float の Infinity ...

すいません。編集途中で送信してしまいました。

修正するのでしばらくお待ち下さい。

----------------------------------------
Bug #15435: Float の Infinity ...
https://bugs.ruby-lang.org/issues/15435#change-75775

* Author: shuujii (Shuji KOBAYASHI)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.6.0rc2 (2018-12-15 trunk 66408) [x86_64-linux]
* Backport: 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------




-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-dev:50718] [Ruby trunk Feature#15435] Float の Infinity に生成済みの値を使用する
       [not found] <redmine.issue-15435.20181219080858@ruby-lang.org>
  2018-12-19  8:08 ` [ruby-dev:50716] [Ruby trunk Bug#15435] Float の Infinity ni shuujii
  2018-12-19  8:13 ` [ruby-dev:50717] [Ruby trunk Bug#15435] Float の Infinity shuujii
@ 2018-12-19  8:54 ` shuujii
  2018-12-20  0:52 ` [ruby-dev:50720] " ko1
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 6+ messages in thread
From: shuujii @ 2018-12-19  8:54 UTC (permalink / raw)
  To: ruby-dev

Issue #15435 has been updated by shuujii (Shuji KOBAYASHI).

File use-predefined-infinity.patch added
File benchmark.yml added
Tracker changed from Bug to Feature
Subject changed from Float の Infinity ... to Float の Infinity に生成済みの値を使用する
ruby -v deleted (ruby 2.6.0rc2 (2018-12-15 trunk 66408) [x86_64-linux])
Backport deleted (2.4: UNKNOWN, 2.5: UNKNOWN)

Float の Infinity はしばしば使われると思うのですが、Flonum が有効でも即値に
ならないので、演算の結果や C から DBL2NUM で返却される場合などに毎回オブ
ジェクトが生成されます。

Ruby リポジトリーで、Infinity オブジェクトが生成されると明確に分かる場所を簡
単に調べた限りでは20数箇所ありました。

~~~
$ grep 'DBL2NUM.*HUGE_VAL' $(git ls-files | awk '/\.c$/ && !/^(spec|ext\/-test-)\//') | wc -l
      21
$ egrep -- '-Float::INFINITY' $(git ls-files | egrep '^(lib|ext)/.*\.rb$') | wc -l
       2
~~~

それで、Infinity の場合は生成済みのオブジェクトを返すようにしてはどうでしょ
うか。

パッチを添付します。添付のベンチマークを benchmark-driver で実行した限りでは、
演算結果が Infinity になる場合は性能が向上し、そうでない場合は有意な差はない
(計測の度にかなりばらつきがあるが概ね10%以内の差におさまる) ようでした。

~~~
Calculating -------------------------------------
                     compare-ruby  built-ruby
   positive_infinity      34.531M     62.540M i/s -      3.000M times in 0.195822s 0.107997s
   negative_infinity      42.581M     94.234M i/s -      3.000M times in 0.159061s 0.071766s
              flonum     142.010M    150.967M i/s -      3.000M times in 0.047544s 0.045120s
                heap      33.952M     34.629M i/s -      3.000M times in 0.199321s 0.195063s

Comparison:
                positive_infinity
          built-ruby:  62540441.7 i/s
        compare-ruby:  34530877.6 i/s - 1.81x  slower

                negative_infinity
          built-ruby:  94234135.1 i/s
        compare-ruby:  42580998.6 i/s - 2.21x  slower

                           flonum
          built-ruby: 150967185.7 i/s
        compare-ruby: 142010146.8 i/s - 1.06x  slower

                             heap
          built-ruby:  34629459.1 i/s
        compare-ruby:  33952081.8 i/s - 1.02x  slower
~~~


----------------------------------------
Feature #15435: Float の Infinity に生成済みの値を使用する
https://bugs.ruby-lang.org/issues/15435#change-75776

* Author: shuujii (Shuji KOBAYASHI)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------


---Files--------------------------------
use-predefined-infinity.patch (8.97 KB)
benchmark.yml (192 Bytes)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-dev:50720] [Ruby trunk Feature#15435] Float の Infinity に生成済みの値を使用する
       [not found] <redmine.issue-15435.20181219080858@ruby-lang.org>
                   ` (2 preceding siblings ...)
  2018-12-19  8:54 ` [ruby-dev:50718] [Ruby trunk Feature#15435] Float の Infinity に生成済みの値を使用する shuujii
@ 2018-12-20  0:52 ` ko1
  2018-12-20  0:52 ` [ruby-dev:50721] " ko1
  2018-12-20 14:27 ` [ruby-dev:50724] " shuujii
  5 siblings, 0 replies; 6+ messages in thread
From: ko1 @ 2018-12-20  0:52 UTC (permalink / raw)
  To: ruby-dev

Issue #15435 has been updated by ko1 (Koichi Sasada).


# コードのご提案時には、アイディア(アルゴリズム)を書いて頂けるとありがたいです。

パッチを見たところ、Flonum 生成時に、範囲外で heap から生成する直前に `isinf()` でチェックして、inf であれば、事前に allocate した inf オブジェクトを返す、と理解しました。

```C
     if (isinf(d)) {
	return d < 0 ? rb_float_negative_infinity : rb_float_positive_infinity;
    }
```

というわけで、`isinf(d)` が入るのを許容できるか、という議論になるんじゃないかと思います。
で、このパスでは heap allocate が入るので、`isinf(d)` check の負荷は問題にならなそうだから、いいような気がします。

でも、ベンチマークで 2% 負荷が増えてるんですね、意外と大きいのかな...。heap にはほとんど落ちないと思っているんですが、heap に落ちる率がわかると、もうちょっと勢いよく、行きましょう! って言えそうです。アプリをお持ちだったりしますか?

以下、その他のコメントです。

>     rb_global_variable(&rb_float_negative_infinity);
>    rb_float_negative_infinity = rb_float_new_in_heap(-HUGE_VAL);

(1) `rb_global_variable` よりも、`rb_gc_register_mark_object` でオブジェクト自体を登録したほうが良いです。
(2) Infinity じゃなくて、いっそ NegativeInfinity という定数も用意してしまったらどうだろう。

benchmark-driver でループ回数指定じゃないモードの方が、この場合良さそうです(どうやるのかよく覚えてない)。


----------------------------------------
Feature #15435: Float の Infinity に生成済みの値を使用する
https://bugs.ruby-lang.org/issues/15435#change-75787

* Author: shuujii (Shuji KOBAYASHI)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Float の Infinity はしばしば使われると思うのですが、Flonum が有効でも即値に
ならないので、演算の結果や C から DBL2NUM で返却される場合などに毎回オブ
ジェクトが生成されます。

Ruby リポジトリーで、Infinity オブジェクトが生成されると明確に分かる場所を簡
単に調べた限りでは20数箇所ありました。

~~~
$ grep 'DBL2NUM.*HUGE_VAL' $(git ls-files | awk '/\.c$/ && !/^(spec|ext\/-test-)\//') | wc -l
      21
$ egrep -- '-Float::INFINITY' $(git ls-files | egrep '^(lib|ext)/.*\.rb$') | wc -l
       2
~~~

それで、Infinity の場合は生成済みのオブジェクトを返すようにしてはどうでしょ
うか。

パッチを添付します。添付のベンチマークを benchmark-driver で実行した限りでは、
演算結果が Infinity になる場合は性能が向上し、そうでない場合は有意な差はない
(計測の度にかなりばらつきがあるが概ね10%以内の差におさまる) ようでした。

~~~
Calculating -------------------------------------
                     compare-ruby  built-ruby
   positive_infinity      34.531M     62.540M i/s -      3.000M times in 0.195822s 0.107997s
   negative_infinity      42.581M     94.234M i/s -      3.000M times in 0.159061s 0.071766s
              flonum     142.010M    150.967M i/s -      3.000M times in 0.047544s 0.045120s
                heap      33.952M     34.629M i/s -      3.000M times in 0.199321s 0.195063s

Comparison:
                positive_infinity
          built-ruby:  62540441.7 i/s
        compare-ruby:  34530877.6 i/s - 1.81x  slower

                negative_infinity
          built-ruby:  94234135.1 i/s
        compare-ruby:  42580998.6 i/s - 2.21x  slower

                           flonum
          built-ruby: 150967185.7 i/s
        compare-ruby: 142010146.8 i/s - 1.06x  slower

                             heap
          built-ruby:  34629459.1 i/s
        compare-ruby:  33952081.8 i/s - 1.02x  slower
~~~

---Files--------------------------------
use-predefined-infinity.patch (8.97 KB)
benchmark.yml (192 Bytes)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-dev:50721] [Ruby trunk Feature#15435] Float の Infinity に生成済みの値を使用する
       [not found] <redmine.issue-15435.20181219080858@ruby-lang.org>
                   ` (3 preceding siblings ...)
  2018-12-20  0:52 ` [ruby-dev:50720] " ko1
@ 2018-12-20  0:52 ` ko1
  2018-12-20 14:27 ` [ruby-dev:50724] " shuujii
  5 siblings, 0 replies; 6+ messages in thread
From: ko1 @ 2018-12-20  0:52 UTC (permalink / raw)
  To: ruby-dev

Issue #15435 has been updated by ko1 (Koichi Sasada).


ko1 (Koichi Sasada) wrote:
> # コードのご提案時には、アイディア(アルゴリズム)を書いて頂けるとありがたいです。
> 
> パッチを見たところ、Flonum 生成時に、範囲外で heap から生成する直前に `isinf()` でチェックして、inf であれば、事前に allocate した inf オブジェクトを返す、と理解しました。
> 
> ```C
>      if (isinf(d)) {
> 	return d < 0 ? rb_float_negative_infinity : rb_float_positive_infinity;
>     }
> ```
> 
> というわけで、`isinf(d)` が入るのを許容できるか、という議論になるんじゃないかと思います。
> で、このパスでは heap allocate が入るので、`isinf(d)` check の負荷は問題にならなそうだから、いいような気がします。
> 
> でも、ベンチマークで 2% 負荷が増えてるんですね、意外と大きいのかな...。heap にはほとんど落ちないと思っているんですが、heap に落ちる率がわかると、もうちょっと勢いよく、行きましょう! って言えそうです。アプリをお持ちだったりしますか?
> 
> 以下、その他のコメントです。
> 
> >     rb_global_variable(&rb_float_negative_infinity);
> >    rb_float_negative_infinity = rb_float_new_in_heap(-HUGE_VAL);
> 
> (1) `rb_global_variable` よりも、`rb_gc_register_mark_object` でオブジェクト自体を登録したほうが良いです。
> (2) Infinity じゃなくて、いっそ NegativeInfinity という定数も用意してしまったらどうだろう。
> 
> benchmark-driver でループ回数指定じゃないモードの方が、この場合良さそうです(どうやるのかよく覚えてない)。



----------------------------------------
Feature #15435: Float の Infinity に生成済みの値を使用する
https://bugs.ruby-lang.org/issues/15435#change-75788

* Author: shuujii (Shuji KOBAYASHI)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Float の Infinity はしばしば使われると思うのですが、Flonum が有効でも即値に
ならないので、演算の結果や C から DBL2NUM で返却される場合などに毎回オブ
ジェクトが生成されます。

Ruby リポジトリーで、Infinity オブジェクトが生成されると明確に分かる場所を簡
単に調べた限りでは20数箇所ありました。

~~~
$ grep 'DBL2NUM.*HUGE_VAL' $(git ls-files | awk '/\.c$/ && !/^(spec|ext\/-test-)\//') | wc -l
      21
$ egrep -- '-Float::INFINITY' $(git ls-files | egrep '^(lib|ext)/.*\.rb$') | wc -l
       2
~~~

それで、Infinity の場合は生成済みのオブジェクトを返すようにしてはどうでしょ
うか。

パッチを添付します。添付のベンチマークを benchmark-driver で実行した限りでは、
演算結果が Infinity になる場合は性能が向上し、そうでない場合は有意な差はない
(計測の度にかなりばらつきがあるが概ね10%以内の差におさまる) ようでした。

~~~
Calculating -------------------------------------
                     compare-ruby  built-ruby
   positive_infinity      34.531M     62.540M i/s -      3.000M times in 0.195822s 0.107997s
   negative_infinity      42.581M     94.234M i/s -      3.000M times in 0.159061s 0.071766s
              flonum     142.010M    150.967M i/s -      3.000M times in 0.047544s 0.045120s
                heap      33.952M     34.629M i/s -      3.000M times in 0.199321s 0.195063s

Comparison:
                positive_infinity
          built-ruby:  62540441.7 i/s
        compare-ruby:  34530877.6 i/s - 1.81x  slower

                negative_infinity
          built-ruby:  94234135.1 i/s
        compare-ruby:  42580998.6 i/s - 2.21x  slower

                           flonum
          built-ruby: 150967185.7 i/s
        compare-ruby: 142010146.8 i/s - 1.06x  slower

                             heap
          built-ruby:  34629459.1 i/s
        compare-ruby:  33952081.8 i/s - 1.02x  slower
~~~

---Files--------------------------------
use-predefined-infinity.patch (8.97 KB)
benchmark.yml (192 Bytes)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-dev:50724] [Ruby trunk Feature#15435] Float の Infinity に生成済みの値を使用する
       [not found] <redmine.issue-15435.20181219080858@ruby-lang.org>
                   ` (4 preceding siblings ...)
  2018-12-20  0:52 ` [ruby-dev:50721] " ko1
@ 2018-12-20 14:27 ` shuujii
  5 siblings, 0 replies; 6+ messages in thread
From: shuujii @ 2018-12-20 14:27 UTC (permalink / raw)
  To: ruby-dev

Issue #15435 has been updated by shuujii (Shuji KOBAYASHI).

File use-predefined-infinity-2.patch added

確認していただいてありがとうございます。

\# 順番がいろいろ前後して回答します。

> 以下、その他のコメントです。
>
> > ~~~
> > rb_global_variable(&rb_float_negative_infinity);
> > rb_float_negative_infinity = rb_float_new_in_heap(-HUGE_VAL);
> > ~~~
>
> (1) rb_global_variable よりも、rb_gc_register_mark_object でオブジェクト自体を登録したほうが良いです。

なるほどー。オブジェクトに対する間接参照が減るということですね (これは
doc/extention.rdoc に載っていると嬉しいのではと思って調べて見たところ、#9894
で提案があったみたいですね)。

修正したパッチを添付します。

> (2) Infinity じゃなくて、いっそ NegativeInfinity という定数も用意してしまったらどうだろう。

これは Float::NEGATIVE_INFINITY を定義するということですよね? それは少し思
いました。Java や JavaScript では POSITIVE_INTINITY と NEGATIVE_INFINITY の
両方が定義されているみたいです。

>(コードのご提案時には、アイディア(アルゴリズム)を書いて頂けるとありがたいです)

すいません、以降気を付けます。

> パッチを見たところ、Flonum 生成時に、範囲外で heap から生成する直前に isinf() でチェックして、inf であれば、事前に allocate した inf オブジェクトを返す、と理解しました。

その通りです。

> heap にはほとんど落ちないと思っているんですが、heap に落ちる率がわかると、もうちょっと勢いよく、行きましょう! って言えそうです。アプリをお持ちだったりしますか?

特にアプリの持ち合わせはありません。

> でも、ベンチマークで 2% 負荷が増えてるんですね、意外と大きいのかな...。

掲載した結果では遅くなっているのではなくて速くなっているんですよね...。ベン
チマークの結果はかなりばらつきが多かったのでたまたまだと思います。

> benchmark-driver でループ回数指定じゃないモードの方が、この場合良さそうです(どうやるのかよく覚えてない)。

確かに、ループ回数を指定しない (YAML で loop_count を指定しない) ほうが結果
はやや安定するようです。ただ、計測環境が悪いのかやり方がまずいのか、それでも
結果は十分に安定しないというか、同一バイナリで比較してみてもほぼ毎回数%の差が
付くので、C の分岐一つなどの影響を厳密に計測するのは今回のやり方では難しいの
かもしれません。何か良い方法はあるでしょうか... (皆さんこういうときはどうやっ
て計測しているのでしょうか...)。

----------------------------------------
Feature #15435: Float の Infinity に生成済みの値を使用する
https://bugs.ruby-lang.org/issues/15435#change-75809

* Author: shuujii (Shuji KOBAYASHI)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Float の Infinity はしばしば使われると思うのですが、Flonum が有効でも即値に
ならないので、演算の結果や C から DBL2NUM で返却される場合などに毎回オブ
ジェクトが生成されます。

Ruby リポジトリーで、Infinity オブジェクトが生成されると明確に分かる場所を簡
単に調べた限りでは20数箇所ありました。

~~~
$ grep 'DBL2NUM.*HUGE_VAL' $(git ls-files | awk '/\.c$/ && !/^(spec|ext\/-test-)\//') | wc -l
      21
$ egrep -- '-Float::INFINITY' $(git ls-files | egrep '^(lib|ext)/.*\.rb$') | wc -l
       2
~~~

それで、Infinity の場合は生成済みのオブジェクトを返すようにしてはどうでしょ
うか。

パッチを添付します。添付のベンチマークを benchmark-driver で実行した限りでは、
演算結果が Infinity になる場合は性能が向上し、そうでない場合は有意な差はない
(計測の度にかなりばらつきがあるが概ね10%以内の差におさまる) ようでした。

~~~
Calculating -------------------------------------
                     compare-ruby  built-ruby
   positive_infinity      34.531M     62.540M i/s -      3.000M times in 0.195822s 0.107997s
   negative_infinity      42.581M     94.234M i/s -      3.000M times in 0.159061s 0.071766s
              flonum     142.010M    150.967M i/s -      3.000M times in 0.047544s 0.045120s
                heap      33.952M     34.629M i/s -      3.000M times in 0.199321s 0.195063s

Comparison:
                positive_infinity
          built-ruby:  62540441.7 i/s
        compare-ruby:  34530877.6 i/s - 1.81x  slower

                negative_infinity
          built-ruby:  94234135.1 i/s
        compare-ruby:  42580998.6 i/s - 2.21x  slower

                           flonum
          built-ruby: 150967185.7 i/s
        compare-ruby: 142010146.8 i/s - 1.06x  slower

                             heap
          built-ruby:  34629459.1 i/s
        compare-ruby:  33952081.8 i/s - 1.02x  slower
~~~

---Files--------------------------------
use-predefined-infinity.patch (8.97 KB)
benchmark.yml (192 Bytes)
use-predefined-infinity-2.patch (8.97 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-12-20 14:27 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <redmine.issue-15435.20181219080858@ruby-lang.org>
2018-12-19  8:08 ` [ruby-dev:50716] [Ruby trunk Bug#15435] Float の Infinity ni shuujii
2018-12-19  8:13 ` [ruby-dev:50717] [Ruby trunk Bug#15435] Float の Infinity shuujii
2018-12-19  8:54 ` [ruby-dev:50718] [Ruby trunk Feature#15435] Float の Infinity に生成済みの値を使用する shuujii
2018-12-20  0:52 ` [ruby-dev:50720] " ko1
2018-12-20  0:52 ` [ruby-dev:50721] " ko1
2018-12-20 14:27 ` [ruby-dev:50724] " shuujii

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).