[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Performance question: Rational

Richard Cole

4/29/2005 1:28:00 AM

I've got a ruby program that's running quite slowly. I ran the profiler
to try to find out what's causing the hold up (see the profile output
below) and it looks like Integer#gcd is a culprit. My code is basically
a canvas with a bunch of canvas items and so it does some integer
computation, but somehow integers are getting converted into rationals
and then being simplified which appears to be taking up heaps of time.

Has anyone got any hints on how to keep rationals out of my program? I
want to stick to integers and floats.

regards,

Richard.


-----
% cumulative self self total
time seconds seconds calls ms/call ms/call name
2578.12 33.00 33.00 1 33000.00 33000.00
Profiler__.start_profile
21.87 33.28 0.28 72 3.89 5.97 Integer#gcd
8.59 33.39 0.11 72 1.53 7.78 Rational#reduce
8.59 33.50 0.11 144 0.76 10.28 Rational#/
7.03 33.59 0.09 146 0.62 0.89 Rational#initialize
6.25 33.67 0.08 1191 0.07 0.07 Fixnum#==
3.91 33.72 0.05 661 0.08 0.08 Fixnum#[]
3.13 33.76 0.04 582 0.07 0.07 Kernel.kind_of?
3.13 33.80 0.04 363 0.11 0.11 Fixnum#>>
3.12 33.84 0.04 326 0.12 0.21
Qt::Base#method_missing
3.12 33.88 0.04 188 0.21 0.96 Class#new
3.12 33.92 0.04 72 0.56 13.33 Fixnum#/
2.34 33.95 0.03 6 5.00 16.67
Griff::CanvasMultiText#draw
1.56 33.97 0.02 150 0.13 0.13 Fixnum#*
1.56 33.99 0.02 114 0.18 0.18
Qt::Internal.find_class
1.56 34.01 0.02 38 0.53 1.05 Qt::Pen#new
1.56 34.03 0.02 364 0.05 0.05 Kernel.class
1.56 34.05 0.02 18 1.11 2.78 Griff::CanvasLine#draw
1.56 34.07 0.02 146 0.14 1.30 Rational#new!
1.56 34.09 0.02 6 3.33 21.67
Griff::CanvasConceptLabel#draw
1.56 34.11 0.02 72 0.28 8.06 Object#Rational
0.78 34.12 0.01 12 0.83 3.33
Griff::CanvasTextStyle#fashion
0.78 34.13 0.01 80 0.13 0.13 Fixnum#>
0.78 34.14 0.01 36 0.28 26.94 Griff::Rect#center
0.78 34.15 0.01 6 1.67 1.67
Griff::CanvasTextStyle#baseline
0.78 34.16 0.01 6 1.67 5.00 Range#each
0.78 34.17 0.01 218 0.05 0.05 Fixnum#<
0.78 34.18 0.01 6 1.67 1.67 Qt::Enum#initialize
0.78 34.19 0.01 6 1.67 1.67
Griff::CanvasTextStyle#left
0.78 34.20 0.01 38 0.26 0.26 Kernel.callcc
0.78 34.21 0.01 6 1.67 11.67
Griff::CanvasMultiText#drawText
0.78 34.22 0.01 8 1.25 2.50
Griff::CanvasEllipse#draw
0.00 34.22 0.00 2 0.00 0.00 Rational#to_f
0.00 34.22 0.00 38 0.00 0.26
Qt::Internal.try_initialize
0.00 34.22 0.00 6 0.00 0.00
Griff::CanvasTextStyle#margin
0.00 34.22 0.00 6 0.00 3.33 Griff::CanvasRect#draw
0.00 34.22 0.00 104 0.00 0.00 Fixnum#-
0.00 34.22 0.00 6 0.00 0.00 Qt::Integer#initialize
0.00 34.22 0.00 6 0.00 0.00
Griff::CanvasTextStyle#height
0.00 34.22 0.00 1 0.00 0.00 Array#sort
0.00 34.22 0.00 38 0.00 0.00 Kernel.method
0.00 34.22 0.00 118 0.00 0.00 Hash#[]
0.00 34.22 0.00 36 0.00 0.00
Griff::Point#initialize
0.00 34.22 0.00 72 0.00 0.00 Fixnum#<<
0.00 34.22 0.00 38 0.00 1.32
Griff::CanvasRectStyle#fashion
0.00 34.22 0.00 42 0.00 0.00 Fixnum#to_f
0.00 34.22 0.00 6 0.00 0.00 Array#[]
0.00 34.22 0.00 94 0.00 0.00 Fixnum#+
0.00 34.22 0.00 6 0.00 0.00
Qt::Internal.get_qenum_type
0.00 34.22 0.00 6 0.00 1.67
Qt::Painter#const_missing
0.00 34.22 0.00 2 0.00 0.00 Float#/
0.00 34.22 0.00 1 0.00 1280.00 #toplevel
0.00 34.22 0.00 6 0.00 0.00
Qt::Internal.get_qinteger
0.00 34.22 0.00 4 0.00 12.50 Griff::Layer#draw
0.00 34.22 0.00 2 0.00 0.00 Rational#coerce
0.00 34.22 0.00 38 0.00 0.00 Qt::Base#initialize
0.00 34.22 0.00 144 0.00 0.00 Fixnum#div
0.00 34.22 0.00 144 0.00 0.00 Fixnum#abs
0.00 34.22 0.00 5 0.00 18.00 Array#each
0.00 34.22 0.00 1 0.00 0.00 Hash#keys
0.00 34.22 0.00 38 0.00 0.00 Float#*
0.00 34.22 0.00 6 0.00 1.67
Qt::Internal.create_qenum
0.00 34.22 0.00 92 0.00 0.00 Float#+



5 Answers

Brian Schröder

4/29/2005 2:11:00 AM

0

On 29/04/05, Richard Cole <rcole@itee.uq.edu.au> wrote:
> I've got a ruby program that's running quite slowly. I ran the profiler
> to try to find out what's causing the hold up (see the profile output
> below) and it looks like Integer#gcd is a culprit. My code is basically
> a canvas with a bunch of canvas items and so it does some integer
> computation, but somehow integers are getting converted into rationals
> and then being simplified which appears to be taking up heaps of time.
>
> Has anyone got any hints on how to keep rationals out of my program? I
> want to stick to integers and floats.
>
> regards,
>
> Richard.
> [snip profiler output]

well, just remove the line
require 'rational'
from your program.

best regards,

Brian

--
http://ruby.brian-sch...

multilingual _non rails_ ruby based vocabulary trainer:
http://www.vocabu... | http://www.g... | http://www.vok...



Richard Cole

4/29/2005 4:36:00 AM

0

Brian Schröder wrote:

>On 29/04/05, Richard Cole <rcole@itee.uq.edu.au> wrote:
>
>
>>I've got a ruby program that's running quite slowly. I ran the profiler
>>to try to find out what's causing the hold up (see the profile output
>>below) and it looks like Integer#gcd is a culprit. My code is basically
>>a canvas with a bunch of canvas items and so it does some integer
>>computation, but somehow integers are getting converted into rationals
>>and then being simplified which appears to be taking up heaps of time.
>>
>>Has anyone got any hints on how to keep rationals out of my program? I
>>want to stick to integers and floats.
>>
>>regards,
>>
>>Richard.
>>[snip profiler output]
>>
>>
>
>well, just remove the line
>require 'rational'
>from your program.
>
>
I wasn't including 'rational'.

I have since discovered that rationals come from the 'mathn' library and
that library is being included by one of the libraries that I'm using. I
also found that x.div(y) produces an integer while x/y produces a
rational, so the answer is to use x.div(y) instead of x/y.

It is kind of freaky to have definition of x/y change dependent on
whether or not a library is included. One library changing the semantics
of the operations defined in another library is side effects on steroids.

irb(main):001:0> 1.div(2)
=> 0
irb(main):002:0> 1/2
=> 0
irb(main):003:0> require 'mathn'
=> true
irb(main):004:0> 1/2
=> 1/2
irb(main):005:0> 1.div(2)
=> 0

So there are three safe combinations (mathn,/), (mathn,div) (none,div)
and one unsafe combination (none,/). It is a pitty that the unsafe
combination is the first one that a nieve programmer would go for. Maybe
this can be cleaned up in the Ruby 2.0?

regards,

Richard.



gabriele renzi

4/29/2005 8:31:00 AM

0

Richard Cole ha scritto:

>
> It is kind of freaky to have definition of x/y change dependent on
> whether or not a library is included. One library changing the semantics
> of the operations defined in another library is side effects on steroids.

yes, and we love that :)
The point of using rational (or complex or mathn or whatever) is that
you're slightly changing the language, so for general purpose you don't
need to support the whole world of chances but you can add them when you
really need them.

> irb(main):001:0> 1.div(2)
> => 0
> irb(main):002:0> 1/2
> => 0
> irb(main):003:0> require 'mathn'
> => true
> irb(main):004:0> 1/2
> => 1/2
> irb(main):005:0> 1.div(2)
> => 0
>
> So there are three safe combinations (mathn,/), (mathn,div) (none,div)
> and one unsafe combination (none,/). It is a pitty that the unsafe
> combination is the first one that a nieve programmer would go for. Maybe
> this can be cleaned up in the Ruby 2.0?
>

see the rcr "make rational a builtin class"
http://rcrchive.net/rc...

timsuth

4/29/2005 8:40:00 AM

0

In article <4271B929.6040900@itee.uq.edu.au>, Richard Cole wrote:
[...]
>I have since discovered that rationals come from the 'mathn' library and
>that library is being included by one of the libraries that I'm using. I
>also found that x.div(y) produces an integer while x/y produces a
>rational, so the answer is to use x.div(y) instead of x/y.
>
>It is kind of freaky to have definition of x/y change dependent on
>whether or not a library is included. One library changing the semantics
>of the operations defined in another library is side effects on steroids.
[...]
>So there are three safe combinations (mathn,/), (mathn,div) (none,div)
>and one unsafe combination (none,/). It is a pitty that the unsafe
>combination is the first one that a nieve programmer would go for. Maybe
>this can be cleaned up in the Ruby 2.0?

Ruby 2.0 will do something with "selector namespaces" that may help here.

See http://www.rubygarden.org...

The effect would be that the library you're using would be able to use
Rationals in the current way, but your own code would not be affected.

timsuth

4/29/2005 8:44:00 AM

0

In article <4hmce.70512$IN.1220555@twister2.libero.it>, gabriele renzi wrote:
>Richard Cole ha scritto:
>
>> It is kind of freaky to have definition of x/y change dependent on
>> whether or not a library is included. One library changing the semantics
>> of the operations defined in another library is side effects on steroids.
>
>yes, and we love that :)
>The point of using rational (or complex or mathn or whatever) is that
>you're slightly changing the language, so for general purpose you don't
>need to support the whole world of chances but you can add them when you
>really need them.
[...]

Problem is though, the original poster didn't do require 'rational'. They
just loaded a library that happened to use rational.

What if you want to use two libraries, one of which requires a/b to be
rational, and the other requires a/b to be integer division?

Selector namespaces are exciting :-)