Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Why Ruby do not optimize code at all?

Reply
Thread Tools

Why Ruby do not optimize code at all?

 
 
Heesob Park
Guest
Posts: n/a
 
      03-28-2008
Hi,

I do not undertand why ruby doesn't do any optimization at all during
parsing time.
Some optimization maybe affects debugging process.
Nevertheless, it seems "Constant folding" is not harmful but helpful.
I tried some pre-evaluation of constant or literal nodes in parsing
time.

Consider this code

i = 320 * 200 * 32

Original ruby-1.8.6 parsed it like this:

0:[NODE_BLOCK],0xb7f93ce4,p1:-9,p2:12,p3:1}
-9:[NODE_NEWLINE],0xb7f93d98,u1:0,u2:1,p3:-17}
-17:[NODE_LASGN],0xb7f93e38,u1:10473,p2:-10,u3:2}
-10:[NODE_CALL],0xb7f93dac,p1:-13,u2:42,p3:-11}
-13:[NODE_CALL],0xb7f93de8,p1:-16,u2:42,p3:-14}
-16:[NODE_LIT],0xb7f93e24,u1:641,u2:0,u3:0}
-14:[NODE_ARRAY],0xb7f93dfc,p1:-15,u2:1,u3:0}
-15:[NODE_LIT],0xb7f93e10,u1:401,u2:0,u3:0}
-11:[NODE_ARRAY],0xb7f93dc0,p1:-12,u2:1,u3:0}
-12:[NODE_LIT],0xb7f93dd4,u1:65,u2:0,u3:0}

My modified ruby parsed it like this:

0:[NODE_BLOCK],0xb7f5cd0c,p1:-9,p2:12,p3:1}
-9:[NODE_NEWLINE],0xb7f5cdc0,u1:0,u2:1,p3:-15}
-15:[NODE_LASGN],0xb7f5ce38,u1:10473,p2:-10,u3:2}
-10:[NODE_LIT],0xb7f5cdd4,u1:4096001,u2:0,u3:0}

A little more complex code

c = (12-3) * Math.sin(100) + 1.300 * (2 + 3) * Math.log(100)

Original parser:
0:[NODE_BLOCK],0xb7f35b08,p1:-9,p2:1,p3:1}
-9:[NODE_NEWLINE],0xb7f35bbc,u1:0,u2:4,p3:-38}
-38:[NODE_LASGN],0xb7f35e00,u1:10473,p2:-10,u3:2}
-10:[NODE_CALL],0xb7f35bd0,p1:-27,u2:43,p3:-11}
-27:[NODE_CALL],0xb7f35d24,p1:-33,u2:42,p3:-28}
-33:[NODE_NEWLINE],0xb7f35d9c,u1:0,u2:4,p3:-34}
-34:[NODE_CALL],0xb7f35db0,p1:-37,u2:45,p3:-35}
-37:[NODE_LIT],0xb7f35dec,u1:25,u2:0,u3:0}
-35:[NODE_ARRAY],0xb7f35dc4,p1:-36,u2:1,u3:0}
-36:[NODE_LIT],0xb7f35dd8,u1:7,u2:0,u3:0}
-28:[NODE_ARRAY],0xb7f35d38,p1:-29,u2:1,u3:0}
-29:[NODE_CALL],0xb7f35d4c,p1:-32,u2:9961,p3:-30}
-32:[NODE_CONST],0xb7f35d88,u1:9925,u2:0,u3:0}
-30:[NODE_ARRAY],0xb7f35d60,p1:-31,u2:1,u3:0}
-31:[NODE_LIT],0xb7f35d74,u1:201,u2:0,u3:0}
-11:[NODE_ARRAY],0xb7f35be4,p1:-12,u2:1,u3:0}
-12:[NODE_CALL],0xb7f35bf8,p1:-18,u2:42,p3:-13}
-18:[NODE_CALL],0xb7f35c70,p1:-25,u2:42,p3:-19}
-25:[NODE_LIT],0xb7f35cfc,p1:-26,u2:0,u3:0}
-19:[NODE_ARRAY],0xb7f35c84,p1:-20,u2:1,u3:0}
-20:[NODE_NEWLINE],0xb7f35c98,u1:0,u2:4,p3:-21}
-21:[NODE_CALL],0xb7f35cac,p1:-24,u2:43,p3:-22}
-24:[NODE_LIT],0xb7f35ce8,u1:5,u2:0,u3:0}
-22:[NODE_ARRAY],0xb7f35cc0,p1:-23,u2:1,u3:0}
-23:[NODE_LIT],0xb7f35cd4,u1:7,u2:0,u3:0}
-13:[NODE_ARRAY],0xb7f35c0c,p1:-14,u2:1,u3:0}
-14:[NODE_CALL],0xb7f35c20,p1:-17,u2:10057,p3:-15}
-17:[NODE_CONST],0xb7f35c5c,u1:9925,u2:0,u3:0}
-15:[NODE_ARRAY],0xb7f35c34,p1:-16,u2:1,u3:0}
-16:[NODE_LIT],0xb7f35c48,u1:201,u2:0,u3:0}
Modified parser:
0:[NODE_BLOCK],0xb7f0fae8,p1:-9,p2:1,p3:1}
-9:[NODE_NEWLINE],0xb7f0fb9c,u1:0,u2:4,p3:-40}
-40:[NODE_LASGN],0xb7f0fe08,u1:10473,p2:-10,u3:2}
-10:[NODE_LIT],0xb7f0fbb0,p1:-11,u2:0,u3:0}

String operation code
s = ("hello " + "world ")*100

Original parser:
0:[NODE_BLOCK],0xb7fa4c74,p1:-11,p2:1,p3:1}
-11:[NODE_NEWLINE],0xb7fa4d50,u1:0,u2:2,p3:-22}
-22:[NODE_LASGN],0xb7fa4e2c,u1:10473,p2:-12,u3:2}
-12:[NODE_CALL],0xb7fa4d64,p1:-15,u2:42,p3:-13}
-15:[NODE_NEWLINE],0xb7fa4da0,u1:0,u2:2,p3:-16}
-16:[NODE_CALL],0xb7fa4db4,p1:-19,u2:43,p3:-21}
-19:[NODE_STR],0xb7fa4df0,p1:-20,u2:0,u3:0}
-21:[NODE_ARRAY],0xb7fa4e18,p1:-17,u2:1,u3:0}
-17:[NODE_STR],0xb7fa4dc8,p1:-18,u2:0,u3:0}
-13:[NODE_ARRAY],0xb7fa4d78,p1:-14,u2:1,u3:0}
-14:[NODE_LIT],0xb7fa4d8c,u1:2001,u2:0,u3:0}

Modified parser:
0:[NODE_BLOCK],0xb7efdc6c,p1:-11,p2:1,p3:1}
-11:[NODE_NEWLINE],0xb7efdd48,u1:0,u2:2,p3:-22}
-22:[NODE_LASGN],0xb7efde24,u1:10473,p2:-12,u3:2}
-12:[NODE_STR],0xb7efdd5c,p1:-13,u2:0,u3:0}

In the loop it make considerable difference
With the code
for i in 1..10000
s = "hello"*10000
end
puts s

Original ruby:
real 0m2.591s
user 0m2.579s
sys 0m0.013s

Modified ruby:
real 0m0.010s
user 0m0.007s
sys 0m0.003s

What do you think of the minimum optimization?

Regards,

Park Heesob
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
 
Jason Roelofs
Guest
Posts: n/a
 
      03-28-2008
On Fri, Mar 28, 2008 at 10:38 AM, Heesob Park <(E-Mail Removed)> wrote:
> Hi,
>
> I do not undertand why ruby doesn't do any optimization at all during
> parsing time.
> Some optimization maybe affects debugging process.
> Nevertheless, it seems "Constant folding" is not harmful but helpful.
> I tried some pre-evaluation of constant or literal nodes in parsing
> time.
>
> Consider this code
>
> i = 320 * 200 * 32
>
> Original ruby-1.8.6 parsed it like this:
>
> 0:[NODE_BLOCK],0xb7f93ce4,p1:-9,p2:12,p3:1}
> -9:[NODE_NEWLINE],0xb7f93d98,u1:0,u2:1,p3:-17}
> -17:[NODE_LASGN],0xb7f93e38,u1:10473,p2:-10,u3:2}
> -10:[NODE_CALL],0xb7f93dac,p1:-13,u2:42,p3:-11}
> -13:[NODE_CALL],0xb7f93de8,p1:-16,u2:42,p3:-14}
> -16:[NODE_LIT],0xb7f93e24,u1:641,u2:0,u3:0}
> -14:[NODE_ARRAY],0xb7f93dfc,p1:-15,u2:1,u3:0}
> -15:[NODE_LIT],0xb7f93e10,u1:401,u2:0,u3:0}
> -11:[NODE_ARRAY],0xb7f93dc0,p1:-12,u2:1,u3:0}
> -12:[NODE_LIT],0xb7f93dd4,u1:65,u2:0,u3:0}
>
> My modified ruby parsed it like this:
>
> 0:[NODE_BLOCK],0xb7f5cd0c,p1:-9,p2:12,p3:1}
> -9:[NODE_NEWLINE],0xb7f5cdc0,u1:0,u2:1,p3:-15}
> -15:[NODE_LASGN],0xb7f5ce38,u1:10473,p2:-10,u3:2}
> -10:[NODE_LIT],0xb7f5cdd4,u1:4096001,u2:0,u3:0}
>
> A little more complex code
>
> c = (12-3) * Math.sin(100) + 1.300 * (2 + 3) * Math.log(100)
>
> Original parser:
> 0:[NODE_BLOCK],0xb7f35b08,p1:-9,p2:1,p3:1}
> -9:[NODE_NEWLINE],0xb7f35bbc,u1:0,u2:4,p3:-38}
> -38:[NODE_LASGN],0xb7f35e00,u1:10473,p2:-10,u3:2}
> -10:[NODE_CALL],0xb7f35bd0,p1:-27,u2:43,p3:-11}
> -27:[NODE_CALL],0xb7f35d24,p1:-33,u2:42,p3:-28}
> -33:[NODE_NEWLINE],0xb7f35d9c,u1:0,u2:4,p3:-34}
> -34:[NODE_CALL],0xb7f35db0,p1:-37,u2:45,p3:-35}
> -37:[NODE_LIT],0xb7f35dec,u1:25,u2:0,u3:0}
> -35:[NODE_ARRAY],0xb7f35dc4,p1:-36,u2:1,u3:0}
> -36:[NODE_LIT],0xb7f35dd8,u1:7,u2:0,u3:0}
> -28:[NODE_ARRAY],0xb7f35d38,p1:-29,u2:1,u3:0}
> -29:[NODE_CALL],0xb7f35d4c,p1:-32,u2:9961,p3:-30}
> -32:[NODE_CONST],0xb7f35d88,u1:9925,u2:0,u3:0}
> -30:[NODE_ARRAY],0xb7f35d60,p1:-31,u2:1,u3:0}
> -31:[NODE_LIT],0xb7f35d74,u1:201,u2:0,u3:0}
> -11:[NODE_ARRAY],0xb7f35be4,p1:-12,u2:1,u3:0}
> -12:[NODE_CALL],0xb7f35bf8,p1:-18,u2:42,p3:-13}
> -18:[NODE_CALL],0xb7f35c70,p1:-25,u2:42,p3:-19}
> -25:[NODE_LIT],0xb7f35cfc,p1:-26,u2:0,u3:0}
> -19:[NODE_ARRAY],0xb7f35c84,p1:-20,u2:1,u3:0}
> -20:[NODE_NEWLINE],0xb7f35c98,u1:0,u2:4,p3:-21}
> -21:[NODE_CALL],0xb7f35cac,p1:-24,u2:43,p3:-22}
> -24:[NODE_LIT],0xb7f35ce8,u1:5,u2:0,u3:0}
> -22:[NODE_ARRAY],0xb7f35cc0,p1:-23,u2:1,u3:0}
> -23:[NODE_LIT],0xb7f35cd4,u1:7,u2:0,u3:0}
> -13:[NODE_ARRAY],0xb7f35c0c,p1:-14,u2:1,u3:0}
> -14:[NODE_CALL],0xb7f35c20,p1:-17,u2:10057,p3:-15}
> -17:[NODE_CONST],0xb7f35c5c,u1:9925,u2:0,u3:0}
> -15:[NODE_ARRAY],0xb7f35c34,p1:-16,u2:1,u3:0}
> -16:[NODE_LIT],0xb7f35c48,u1:201,u2:0,u3:0}
> Modified parser:
> 0:[NODE_BLOCK],0xb7f0fae8,p1:-9,p2:1,p3:1}
> -9:[NODE_NEWLINE],0xb7f0fb9c,u1:0,u2:4,p3:-40}
> -40:[NODE_LASGN],0xb7f0fe08,u1:10473,p2:-10,u3:2}
> -10:[NODE_LIT],0xb7f0fbb0,p1:-11,u2:0,u3:0}
>
> String operation code
> s = ("hello " + "world ")*100
>
> Original parser:
> 0:[NODE_BLOCK],0xb7fa4c74,p1:-11,p2:1,p3:1}
> -11:[NODE_NEWLINE],0xb7fa4d50,u1:0,u2:2,p3:-22}
> -22:[NODE_LASGN],0xb7fa4e2c,u1:10473,p2:-12,u3:2}
> -12:[NODE_CALL],0xb7fa4d64,p1:-15,u2:42,p3:-13}
> -15:[NODE_NEWLINE],0xb7fa4da0,u1:0,u2:2,p3:-16}
> -16:[NODE_CALL],0xb7fa4db4,p1:-19,u2:43,p3:-21}
> -19:[NODE_STR],0xb7fa4df0,p1:-20,u2:0,u3:0}
> -21:[NODE_ARRAY],0xb7fa4e18,p1:-17,u2:1,u3:0}
> -17:[NODE_STR],0xb7fa4dc8,p1:-18,u2:0,u3:0}
> -13:[NODE_ARRAY],0xb7fa4d78,p1:-14,u2:1,u3:0}
> -14:[NODE_LIT],0xb7fa4d8c,u1:2001,u2:0,u3:0}
>
> Modified parser:
> 0:[NODE_BLOCK],0xb7efdc6c,p1:-11,p2:1,p3:1}
> -11:[NODE_NEWLINE],0xb7efdd48,u1:0,u2:2,p3:-22}
> -22:[NODE_LASGN],0xb7efde24,u1:10473,p2:-12,u3:2}
> -12:[NODE_STR],0xb7efdd5c,p1:-13,u2:0,u3:0}
>
> In the loop it make considerable difference
> With the code
> for i in 1..10000
> s = "hello"*10000
> end
> puts s
>
> Original ruby:
> real 0m2.591s
> user 0m2.579s
> sys 0m0.013s
>
> Modified ruby:
> real 0m0.010s
> user 0m0.007s
> sys 0m0.003s
>
> What do you think of the minimum optimization?
>
> Regards,
>
> Park Heesob
> --
> Posted via http://www.ruby-forum.com/.
>
>


I guess the first question is does Ruby with your parser changes pass
all the tests?

Second, could you post a patch for people to try out and evaluate?
We'll need to see the actual code to really evaluate if you've got
something here.

Jason

 
Reply With Quote
 
 
 
 
Jason Roelofs
Guest
Posts: n/a
 
      03-28-2008
On Fri, Mar 28, 2008 at 10:45 AM, Jason Roelofs <(E-Mail Removed)> wrote:
>
> On Fri, Mar 28, 2008 at 10:38 AM, Heesob Park <(E-Mail Removed)> wrote:
> > Hi,
> >
> > I do not undertand why ruby doesn't do any optimization at all during
> > parsing time.
> > Some optimization maybe affects debugging process.
> > Nevertheless, it seems "Constant folding" is not harmful but helpful.
> > I tried some pre-evaluation of constant or literal nodes in parsing
> > time.
> >
> > Consider this code
> >
> > i = 320 * 200 * 32
> >
> > Original ruby-1.8.6 parsed it like this:
> >
> > 0:[NODE_BLOCK],0xb7f93ce4,p1:-9,p2:12,p3:1}
> > -9:[NODE_NEWLINE],0xb7f93d98,u1:0,u2:1,p3:-17}
> > -17:[NODE_LASGN],0xb7f93e38,u1:10473,p2:-10,u3:2}
> > -10:[NODE_CALL],0xb7f93dac,p1:-13,u2:42,p3:-11}
> > -13:[NODE_CALL],0xb7f93de8,p1:-16,u2:42,p3:-14}
> > -16:[NODE_LIT],0xb7f93e24,u1:641,u2:0,u3:0}
> > -14:[NODE_ARRAY],0xb7f93dfc,p1:-15,u2:1,u3:0}
> > -15:[NODE_LIT],0xb7f93e10,u1:401,u2:0,u3:0}
> > -11:[NODE_ARRAY],0xb7f93dc0,p1:-12,u2:1,u3:0}
> > -12:[NODE_LIT],0xb7f93dd4,u1:65,u2:0,u3:0}
> >
> > My modified ruby parsed it like this:
> >
> > 0:[NODE_BLOCK],0xb7f5cd0c,p1:-9,p2:12,p3:1}
> > -9:[NODE_NEWLINE],0xb7f5cdc0,u1:0,u2:1,p3:-15}
> > -15:[NODE_LASGN],0xb7f5ce38,u1:10473,p2:-10,u3:2}
> > -10:[NODE_LIT],0xb7f5cdd4,u1:4096001,u2:0,u3:0}
> >
> > A little more complex code
> >
> > c = (12-3) * Math.sin(100) + 1.300 * (2 + 3) * Math.log(100)
> >
> > Original parser:
> > 0:[NODE_BLOCK],0xb7f35b08,p1:-9,p2:1,p3:1}
> > -9:[NODE_NEWLINE],0xb7f35bbc,u1:0,u2:4,p3:-38}
> > -38:[NODE_LASGN],0xb7f35e00,u1:10473,p2:-10,u3:2}
> > -10:[NODE_CALL],0xb7f35bd0,p1:-27,u2:43,p3:-11}
> > -27:[NODE_CALL],0xb7f35d24,p1:-33,u2:42,p3:-28}
> > -33:[NODE_NEWLINE],0xb7f35d9c,u1:0,u2:4,p3:-34}
> > -34:[NODE_CALL],0xb7f35db0,p1:-37,u2:45,p3:-35}
> > -37:[NODE_LIT],0xb7f35dec,u1:25,u2:0,u3:0}
> > -35:[NODE_ARRAY],0xb7f35dc4,p1:-36,u2:1,u3:0}
> > -36:[NODE_LIT],0xb7f35dd8,u1:7,u2:0,u3:0}
> > -28:[NODE_ARRAY],0xb7f35d38,p1:-29,u2:1,u3:0}
> > -29:[NODE_CALL],0xb7f35d4c,p1:-32,u2:9961,p3:-30}
> > -32:[NODE_CONST],0xb7f35d88,u1:9925,u2:0,u3:0}
> > -30:[NODE_ARRAY],0xb7f35d60,p1:-31,u2:1,u3:0}
> > -31:[NODE_LIT],0xb7f35d74,u1:201,u2:0,u3:0}
> > -11:[NODE_ARRAY],0xb7f35be4,p1:-12,u2:1,u3:0}
> > -12:[NODE_CALL],0xb7f35bf8,p1:-18,u2:42,p3:-13}
> > -18:[NODE_CALL],0xb7f35c70,p1:-25,u2:42,p3:-19}
> > -25:[NODE_LIT],0xb7f35cfc,p1:-26,u2:0,u3:0}
> > -19:[NODE_ARRAY],0xb7f35c84,p1:-20,u2:1,u3:0}
> > -20:[NODE_NEWLINE],0xb7f35c98,u1:0,u2:4,p3:-21}
> > -21:[NODE_CALL],0xb7f35cac,p1:-24,u2:43,p3:-22}
> > -24:[NODE_LIT],0xb7f35ce8,u1:5,u2:0,u3:0}
> > -22:[NODE_ARRAY],0xb7f35cc0,p1:-23,u2:1,u3:0}
> > -23:[NODE_LIT],0xb7f35cd4,u1:7,u2:0,u3:0}
> > -13:[NODE_ARRAY],0xb7f35c0c,p1:-14,u2:1,u3:0}
> > -14:[NODE_CALL],0xb7f35c20,p1:-17,u2:10057,p3:-15}
> > -17:[NODE_CONST],0xb7f35c5c,u1:9925,u2:0,u3:0}
> > -15:[NODE_ARRAY],0xb7f35c34,p1:-16,u2:1,u3:0}
> > -16:[NODE_LIT],0xb7f35c48,u1:201,u2:0,u3:0}
> > Modified parser:
> > 0:[NODE_BLOCK],0xb7f0fae8,p1:-9,p2:1,p3:1}
> > -9:[NODE_NEWLINE],0xb7f0fb9c,u1:0,u2:4,p3:-40}
> > -40:[NODE_LASGN],0xb7f0fe08,u1:10473,p2:-10,u3:2}
> > -10:[NODE_LIT],0xb7f0fbb0,p1:-11,u2:0,u3:0}
> >
> > String operation code
> > s = ("hello " + "world ")*100
> >
> > Original parser:
> > 0:[NODE_BLOCK],0xb7fa4c74,p1:-11,p2:1,p3:1}
> > -11:[NODE_NEWLINE],0xb7fa4d50,u1:0,u2:2,p3:-22}
> > -22:[NODE_LASGN],0xb7fa4e2c,u1:10473,p2:-12,u3:2}
> > -12:[NODE_CALL],0xb7fa4d64,p1:-15,u2:42,p3:-13}
> > -15:[NODE_NEWLINE],0xb7fa4da0,u1:0,u2:2,p3:-16}
> > -16:[NODE_CALL],0xb7fa4db4,p1:-19,u2:43,p3:-21}
> > -19:[NODE_STR],0xb7fa4df0,p1:-20,u2:0,u3:0}
> > -21:[NODE_ARRAY],0xb7fa4e18,p1:-17,u2:1,u3:0}
> > -17:[NODE_STR],0xb7fa4dc8,p1:-18,u2:0,u3:0}
> > -13:[NODE_ARRAY],0xb7fa4d78,p1:-14,u2:1,u3:0}
> > -14:[NODE_LIT],0xb7fa4d8c,u1:2001,u2:0,u3:0}
> >
> > Modified parser:
> > 0:[NODE_BLOCK],0xb7efdc6c,p1:-11,p2:1,p3:1}
> > -11:[NODE_NEWLINE],0xb7efdd48,u1:0,u2:2,p3:-22}
> > -22:[NODE_LASGN],0xb7efde24,u1:10473,p2:-12,u3:2}
> > -12:[NODE_STR],0xb7efdd5c,p1:-13,u2:0,u3:0}
> >
> > In the loop it make considerable difference
> > With the code
> > for i in 1..10000
> > s = "hello"*10000
> > end
> > puts s
> >
> > Original ruby:
> > real 0m2.591s
> > user 0m2.579s
> > sys 0m0.013s
> >
> > Modified ruby:
> > real 0m0.010s
> > user 0m0.007s
> > sys 0m0.003s
> >
> > What do you think of the minimum optimization?
> >
> > Regards,
> >
> > Park Heesob
> > --
> > Posted via http://www.ruby-forum.com/.
> >
> >

>
> I guess the first question is does Ruby with your parser changes pass
> all the tests?
>
> Second, could you post a patch for people to try out and evaluate?
> We'll need to see the actual code to really evaluate if you've got
> something here.
>
> Jason
>


Oh, and this belongs in the Ruby Core mailing list.

Jason

 
Reply With Quote
 
ts
Guest
Posts: n/a
 
      03-28-2008
Heesob Park wrote:
> String operation code
> s = ("hello " + "world ")*100
>


[...]

> Modified parser:
> 0:[NODE_BLOCK],0xb7efdc6c,p1:-11,p2:1,p3:1}
> -11:[NODE_NEWLINE],0xb7efdd48,u1:0,u2:2,p3:-22}
> -22:[NODE_LASGN],0xb7efde24,u1:10473,p2:-12,u3:2}
> -12:[NODE_STR],0xb7efdd5c,p1:-13,u2:0,u3:0}


What do you do, if someone write this

vgs% /usr/bin/ruby
class String
def +(x)
"#{x} #{self}"
end
end

p "a" + "b"
^D
"b a"
vgs%

I know, the example is stupid




Guy Decoux

 
Reply With Quote
 
Chiyuan Zhang
Guest
Posts: n/a
 
      03-28-2008
I think the problem is that you can redefine any method
of any class at any time. If some one redefined the `*'
method of Fixnum, your code won't pass, I guess.

2008/3/28, Heesob Park <(E-Mail Removed)>:
> Hi,
>
> I do not undertand why ruby doesn't do any optimization at all during
> parsing time.
> Some optimization maybe affects debugging process.
> Nevertheless, it seems "Constant folding" is not harmful but helpful.
> I tried some pre-evaluation of constant or literal nodes in parsing
> time.
>
> Consider this code
>
> i = 320 * 200 * 32
>
> Original ruby-1.8.6 parsed it like this:
>
> 0:[NODE_BLOCK],0xb7f93ce4,p1:-9,p2:12,p3:1}
> -9:[NODE_NEWLINE],0xb7f93d98,u1:0,u2:1,p3:-17}
> -17:[NODE_LASGN],0xb7f93e38,u1:10473,p2:-10,u3:2}
> -10:[NODE_CALL],0xb7f93dac,p1:-13,u2:42,p3:-11}
> -13:[NODE_CALL],0xb7f93de8,p1:-16,u2:42,p3:-14}
> -16:[NODE_LIT],0xb7f93e24,u1:641,u2:0,u3:0}
> -14:[NODE_ARRAY],0xb7f93dfc,p1:-15,u2:1,u3:0}
> -15:[NODE_LIT],0xb7f93e10,u1:401,u2:0,u3:0}
> -11:[NODE_ARRAY],0xb7f93dc0,p1:-12,u2:1,u3:0}
> -12:[NODE_LIT],0xb7f93dd4,u1:65,u2:0,u3:0}
>
> My modified ruby parsed it like this:
>
> 0:[NODE_BLOCK],0xb7f5cd0c,p1:-9,p2:12,p3:1}
> -9:[NODE_NEWLINE],0xb7f5cdc0,u1:0,u2:1,p3:-15}
> -15:[NODE_LASGN],0xb7f5ce38,u1:10473,p2:-10,u3:2}
> -10:[NODE_LIT],0xb7f5cdd4,u1:4096001,u2:0,u3:0}
>
> A little more complex code
>
> c = (12-3) * Math.sin(100) + 1.300 * (2 + 3) * Math.log(100)
>
> Original parser:
> 0:[NODE_BLOCK],0xb7f35b08,p1:-9,p2:1,p3:1}
> -9:[NODE_NEWLINE],0xb7f35bbc,u1:0,u2:4,p3:-38}
> -38:[NODE_LASGN],0xb7f35e00,u1:10473,p2:-10,u3:2}
> -10:[NODE_CALL],0xb7f35bd0,p1:-27,u2:43,p3:-11}
> -27:[NODE_CALL],0xb7f35d24,p1:-33,u2:42,p3:-28}
> -33:[NODE_NEWLINE],0xb7f35d9c,u1:0,u2:4,p3:-34}
> -34:[NODE_CALL],0xb7f35db0,p1:-37,u2:45,p3:-35}
> -37:[NODE_LIT],0xb7f35dec,u1:25,u2:0,u3:0}
> -35:[NODE_ARRAY],0xb7f35dc4,p1:-36,u2:1,u3:0}
> -36:[NODE_LIT],0xb7f35dd8,u1:7,u2:0,u3:0}
> -28:[NODE_ARRAY],0xb7f35d38,p1:-29,u2:1,u3:0}
> -29:[NODE_CALL],0xb7f35d4c,p1:-32,u2:9961,p3:-30}
> -32:[NODE_CONST],0xb7f35d88,u1:9925,u2:0,u3:0}
> -30:[NODE_ARRAY],0xb7f35d60,p1:-31,u2:1,u3:0}
> -31:[NODE_LIT],0xb7f35d74,u1:201,u2:0,u3:0}
> -11:[NODE_ARRAY],0xb7f35be4,p1:-12,u2:1,u3:0}
> -12:[NODE_CALL],0xb7f35bf8,p1:-18,u2:42,p3:-13}
> -18:[NODE_CALL],0xb7f35c70,p1:-25,u2:42,p3:-19}
> -25:[NODE_LIT],0xb7f35cfc,p1:-26,u2:0,u3:0}
> -19:[NODE_ARRAY],0xb7f35c84,p1:-20,u2:1,u3:0}
> -20:[NODE_NEWLINE],0xb7f35c98,u1:0,u2:4,p3:-21}
> -21:[NODE_CALL],0xb7f35cac,p1:-24,u2:43,p3:-22}
> -24:[NODE_LIT],0xb7f35ce8,u1:5,u2:0,u3:0}
> -22:[NODE_ARRAY],0xb7f35cc0,p1:-23,u2:1,u3:0}
> -23:[NODE_LIT],0xb7f35cd4,u1:7,u2:0,u3:0}
> -13:[NODE_ARRAY],0xb7f35c0c,p1:-14,u2:1,u3:0}
> -14:[NODE_CALL],0xb7f35c20,p1:-17,u2:10057,p3:-15}
> -17:[NODE_CONST],0xb7f35c5c,u1:9925,u2:0,u3:0}
> -15:[NODE_ARRAY],0xb7f35c34,p1:-16,u2:1,u3:0}
> -16:[NODE_LIT],0xb7f35c48,u1:201,u2:0,u3:0}
> Modified parser:
> 0:[NODE_BLOCK],0xb7f0fae8,p1:-9,p2:1,p3:1}
> -9:[NODE_NEWLINE],0xb7f0fb9c,u1:0,u2:4,p3:-40}
> -40:[NODE_LASGN],0xb7f0fe08,u1:10473,p2:-10,u3:2}
> -10:[NODE_LIT],0xb7f0fbb0,p1:-11,u2:0,u3:0}
>
> String operation code
> s = ("hello " + "world ")*100
>
> Original parser:
> 0:[NODE_BLOCK],0xb7fa4c74,p1:-11,p2:1,p3:1}
> -11:[NODE_NEWLINE],0xb7fa4d50,u1:0,u2:2,p3:-22}
> -22:[NODE_LASGN],0xb7fa4e2c,u1:10473,p2:-12,u3:2}
> -12:[NODE_CALL],0xb7fa4d64,p1:-15,u2:42,p3:-13}
> -15:[NODE_NEWLINE],0xb7fa4da0,u1:0,u2:2,p3:-16}
> -16:[NODE_CALL],0xb7fa4db4,p1:-19,u2:43,p3:-21}
> -19:[NODE_STR],0xb7fa4df0,p1:-20,u2:0,u3:0}
> -21:[NODE_ARRAY],0xb7fa4e18,p1:-17,u2:1,u3:0}
> -17:[NODE_STR],0xb7fa4dc8,p1:-18,u2:0,u3:0}
> -13:[NODE_ARRAY],0xb7fa4d78,p1:-14,u2:1,u3:0}
> -14:[NODE_LIT],0xb7fa4d8c,u1:2001,u2:0,u3:0}
>
> Modified parser:
> 0:[NODE_BLOCK],0xb7efdc6c,p1:-11,p2:1,p3:1}
> -11:[NODE_NEWLINE],0xb7efdd48,u1:0,u2:2,p3:-22}
> -22:[NODE_LASGN],0xb7efde24,u1:10473,p2:-12,u3:2}
> -12:[NODE_STR],0xb7efdd5c,p1:-13,u2:0,u3:0}
>
> In the loop it make considerable difference
> With the code
> for i in 1..10000
> s = "hello"*10000
> end
> puts s
>
> Original ruby:
> real 0m2.591s
> user 0m2.579s
> sys 0m0.013s
>
> Modified ruby:
> real 0m0.010s
> user 0m0.007s
> sys 0m0.003s
>
> What do you think of the minimum optimization?
>
> Regards,
>
> Park Heesob
>
> --
> Posted via http://www.ruby-forum.com/.
>
>


 
Reply With Quote
 
James Tucker
Guest
Posts: n/a
 
      03-28-2008

On 28 Mar 2008, at 15:20, Chiyuan Zhang wrote:
> I think the problem is that you can redefine any method
> of any class at any time. If some one redefined the `*'
> method of Fixnum, your code won't pass, I guess.


More than this, it may not even be a fixnum or string or whatever
instance class. Not even constants are 'constant'.

> 2008/3/28, Heesob Park <(E-Mail Removed)>:
>> Hi,
>>
>> I do not undertand why ruby doesn't do any optimization at all during
>> parsing time.


The AST defines very little, if anything, about what the code will do,
until it is considered as a whole. (Which may not be possible if there
is any eval().

>> Some optimization maybe affects debugging process.
>> Nevertheless, it seems "Constant folding" is not harmful but helpful.
>> I tried some pre-evaluation of constant or literal nodes in parsing
>> time.


As said by others, open classes means parse time != run time, at all.

>> Consider this code
>>
>> i = 320 * 200 * 32


The only time I could see this being sensible to do is if it's
actually closer to:

A = 320.freeze
B = 200.freeze
C = 32.freeze

i = A * B * C

However, the realistic implications are that freeze plus the discussed
optimization causes a pre-processor fixed definition of the methods
A.*() and B.*().

In MRI, one can unfreeze too, so this still isn't "safe", and the
source code does not resemble what is run.

This will kick people most, when reading someone else code.

>>
>> What do you think of the minimum optimization?


I think it shows up immediately in profiling if it's relevant, as if
it is relevant, you will highly likely see a large number of calls to
Fixnum#*, and in some of the given examples, this is exactly where
you'd manually unroll to optimize for speed, or alternatively:

BIG_NUMBER = 100_000 * 100
SOMETHING_THAT_SHOULD_BE_A_CONSTANT = BIG_NUMBER * 'some string'

def foo
SOMETHING_THAT_SHOULD_BE_A_CONSTANT
end

>> Regards,
>>
>> Park Heesob
>>
>> --
>> Posted via http://www.ruby-forum.com/.


 
Reply With Quote
 
Park Heesob
Guest
Posts: n/a
 
      03-28-2008
SGksDQotLS0tLSBPcmlnaW5hbCBNZXNzYWdlIC0tLS0tIA0KRn JvbTogIkphc29uIFJvZWxvZnMi
IDxqYW1lc2tpbHRvbkBnbWFpbC5jb20+DQpUbzogInJ1YnktdG FsayBNTCIgPHJ1YnktdGFsa0By
dWJ5LWxhbmcub3JnPjsgPHJ1YnktY29yZUBydWJ5LWxhbmcub3 JnPg0KU2VudDogRnJpZGF5LCBN
YXJjaCAyOCwgMjAwOCAxMTo1MyBQTQ0KU3ViamVjdDogUmU6IF doeSBSdWJ5IGRvIG5vdCBvcHRp
bWl6ZSBjb2RlIGF0IGFsbD8NCg0KDQo+IE9uIEZyaSwgTWFyID I4LCAyMDA4IGF0IDEwOjQ1IEFN
LCBKYXNvbiBSb2Vsb2ZzIDxqYW1lc2tpbHRvbkBnbWFpbC5jb2 0+IHdyb3RlOg0KPj4NCi4uDQo+
PiAgSSBndWVzcyB0aGUgZmlyc3QgcXVlc3Rpb24gaXMgZG9lcy BSdWJ5IHdpdGggeW91ciBwYXJz
ZXIgY2hhbmdlcyBwYXNzDQo+PiAgYWxsIHRoZSB0ZXN0cz8NCj 4+DQo+PiAgU2Vjb25kLCBjb3Vs
ZCB5b3UgcG9zdCBhIHBhdGNoIGZvciBwZW9wbGUgdG8gdHJ5IG 91dCBhbmQgZXZhbHVhdGU/DQo+
PiAgV2UnbGwgbmVlZCB0byBzZWUgdGhlIGFjdHVhbCBjb2RlIH RvIHJlYWxseSBldmFsdWF0ZSBp
ZiB5b3UndmUgZ290DQo+PiAgc29tZXRoaW5nIGhlcmUuDQo+Pg 0KPj4gIEphc29uDQo+Pg0KPiAN
Cj4gT2gsIGFuZCB0aGlzIGJlbG9uZ3MgaW4gdGhlIFJ1YnkgQ2 9yZSBtYWlsaW5nIGxpc3QuDQo+
IA0KPiBKYXNvbg0KPiANCj4NCk5ldmVyIG1pbmQsIEkgZ2F2ZS BpdCB1cC4NCg0KUmVnYXJkcywN
Cg0KUGFyayBIZWVzb2INCg==


 
Reply With Quote
 
ts
Guest
Posts: n/a
 
      03-28-2008
Park Heesob wrote:
> So ruby is never fast but flexible language


Well I can give you another example of "premature" optimisation, but
for 1.9

[ruby-bugs:16163]


http://rubyforge.org/tracker/index.p...=426&atid=1698

it worked but a modification was made to ruby and the optimisation
break the code now



Guy Decoux



 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      03-28-2008
On 28.03.2008 15:38, Heesob Park wrote:
> I do not undertand why ruby doesn't do any optimization at all during
> parsing time.


Because, as others have pointed out already, at parse time it is not
known what the code will do.

> Some optimization maybe affects debugging process.
> Nevertheless, it seems "Constant folding" is not harmful but helpful.
> I tried some pre-evaluation of constant or literal nodes in parsing
> time.
>
> Consider this code
>
> i = 320 * 200 * 32
>
> Original ruby-1.8.6 parsed it like this:
>
> 0:[NODE_BLOCK],0xb7f93ce4,p1:-9,p2:12,p3:1}
> -9:[NODE_NEWLINE],0xb7f93d98,u1:0,u2:1,p3:-17}
> -17:[NODE_LASGN],0xb7f93e38,u1:10473,p2:-10,u3:2}
> -10:[NODE_CALL],0xb7f93dac,p1:-13,u2:42,p3:-11}
> -13:[NODE_CALL],0xb7f93de8,p1:-16,u2:42,p3:-14}
> -16:[NODE_LIT],0xb7f93e24,u1:641,u2:0,u3:0}
> -14:[NODE_ARRAY],0xb7f93dfc,p1:-15,u2:1,u3:0}
> -15:[NODE_LIT],0xb7f93e10,u1:401,u2:0,u3:0}
> -11:[NODE_ARRAY],0xb7f93dc0,p1:-12,u2:1,u3:0}
> -12:[NODE_LIT],0xb7f93dd4,u1:65,u2:0,u3:0}
>
> My modified ruby parsed it like this:
>
> 0:[NODE_BLOCK],0xb7f5cd0c,p1:-9,p2:12,p3:1}
> -9:[NODE_NEWLINE],0xb7f5cdc0,u1:0,u2:1,p3:-15}
> -15:[NODE_LASGN],0xb7f5ce38,u1:10473,p2:-10,u3:2}
> -10:[NODE_LIT],0xb7f5cdd4,u1:4096001,u2:0,u3:0}


$ ruby -e 'class Fixnum; def *(o) 666 end;end; puts 320 * 200 * 32'
666

Ooops!

Without fiddling:

robert@fussel ~
$ ruby -e 'puts 1/2'
0

robert@fussel ~
$ ruby -r mathn -e 'puts 1/2'
1/2

> A little more complex code
>
> c = (12-3) * Math.sin(100) + 1.300 * (2 + 3) * Math.log(100)
>
> Original parser:
> 0:[NODE_BLOCK],0xb7f35b08,p1:-9,p2:1,p3:1}
> -9:[NODE_NEWLINE],0xb7f35bbc,u1:0,u2:4,p3:-38}
> -38:[NODE_LASGN],0xb7f35e00,u1:10473,p2:-10,u3:2}
> -10:[NODE_CALL],0xb7f35bd0,p1:-27,u2:43,p3:-11}
> -27:[NODE_CALL],0xb7f35d24,p1:-33,u2:42,p3:-28}
> -33:[NODE_NEWLINE],0xb7f35d9c,u1:0,u2:4,p3:-34}
> -34:[NODE_CALL],0xb7f35db0,p1:-37,u2:45,p3:-35}
> -37:[NODE_LIT],0xb7f35dec,u1:25,u2:0,u3:0}
> -35:[NODE_ARRAY],0xb7f35dc4,p1:-36,u2:1,u3:0}
> -36:[NODE_LIT],0xb7f35dd8,u1:7,u2:0,u3:0}
> -28:[NODE_ARRAY],0xb7f35d38,p1:-29,u2:1,u3:0}
> -29:[NODE_CALL],0xb7f35d4c,p1:-32,u2:9961,p3:-30}
> -32:[NODE_CONST],0xb7f35d88,u1:9925,u2:0,u3:0}
> -30:[NODE_ARRAY],0xb7f35d60,p1:-31,u2:1,u3:0}
> -31:[NODE_LIT],0xb7f35d74,u1:201,u2:0,u3:0}
> -11:[NODE_ARRAY],0xb7f35be4,p1:-12,u2:1,u3:0}
> -12:[NODE_CALL],0xb7f35bf8,p1:-18,u2:42,p3:-13}
> -18:[NODE_CALL],0xb7f35c70,p1:-25,u2:42,p3:-19}
> -25:[NODE_LIT],0xb7f35cfc,p1:-26,u2:0,u3:0}
> -19:[NODE_ARRAY],0xb7f35c84,p1:-20,u2:1,u3:0}
> -20:[NODE_NEWLINE],0xb7f35c98,u1:0,u2:4,p3:-21}
> -21:[NODE_CALL],0xb7f35cac,p1:-24,u2:43,p3:-22}
> -24:[NODE_LIT],0xb7f35ce8,u1:5,u2:0,u3:0}
> -22:[NODE_ARRAY],0xb7f35cc0,p1:-23,u2:1,u3:0}
> -23:[NODE_LIT],0xb7f35cd4,u1:7,u2:0,u3:0}
> -13:[NODE_ARRAY],0xb7f35c0c,p1:-14,u2:1,u3:0}
> -14:[NODE_CALL],0xb7f35c20,p1:-17,u2:10057,p3:-15}
> -17:[NODE_CONST],0xb7f35c5c,u1:9925,u2:0,u3:0}
> -15:[NODE_ARRAY],0xb7f35c34,p1:-16,u2:1,u3:0}
> -16:[NODE_LIT],0xb7f35c48,u1:201,u2:0,u3:0}
> Modified parser:
> 0:[NODE_BLOCK],0xb7f0fae8,p1:-9,p2:1,p3:1}
> -9:[NODE_NEWLINE],0xb7f0fb9c,u1:0,u2:4,p3:-40}
> -40:[NODE_LASGN],0xb7f0fe08,u1:10473,p2:-10,u3:2}
> -10:[NODE_LIT],0xb7f0fbb0,p1:-11,u2:0,u3:0}


Same story as above.

> String operation code
> s = ("hello " + "world ")*100


Note that in the code above the only constant is "100". The sequence
"hello" is a String constructor - not a constant - as you can easily see:

irb(main):012:0> (1..5).map { "hello".object_id }
=> [1073415980, 1073415960, 1073415940, 1073415920, 1073415900]
irb(main):013:0> (1..5).map { "hello".object_id }.uniq
=> [1073407290, 1073407270, 1073407250, 1073407230, 1073407210]

> Original parser:
> 0:[NODE_BLOCK],0xb7fa4c74,p1:-11,p2:1,p3:1}
> -11:[NODE_NEWLINE],0xb7fa4d50,u1:0,u2:2,p3:-22}
> -22:[NODE_LASGN],0xb7fa4e2c,u1:10473,p2:-12,u3:2}
> -12:[NODE_CALL],0xb7fa4d64,p1:-15,u2:42,p3:-13}
> -15:[NODE_NEWLINE],0xb7fa4da0,u1:0,u2:2,p3:-16}
> -16:[NODE_CALL],0xb7fa4db4,p1:-19,u2:43,p3:-21}
> -19:[NODE_STR],0xb7fa4df0,p1:-20,u2:0,u3:0}
> -21:[NODE_ARRAY],0xb7fa4e18,p1:-17,u2:1,u3:0}
> -17:[NODE_STR],0xb7fa4dc8,p1:-18,u2:0,u3:0}
> -13:[NODE_ARRAY],0xb7fa4d78,p1:-14,u2:1,u3:0}
> -14:[NODE_LIT],0xb7fa4d8c,u1:2001,u2:0,u3:0}
>
> Modified parser:
> 0:[NODE_BLOCK],0xb7efdc6c,p1:-11,p2:1,p3:1}
> -11:[NODE_NEWLINE],0xb7efdd48,u1:0,u2:2,p3:-22}
> -22:[NODE_LASGN],0xb7efde24,u1:10473,p2:-12,u3:2}
> -12:[NODE_STR],0xb7efdd5c,p1:-13,u2:0,u3:0}
>
> In the loop it make considerable difference
> With the code
> for i in 1..10000
> s = "hello"*10000
> end
> puts s
>
> Original ruby:
> real 0m2.591s
> user 0m2.579s
> sys 0m0.013s
>
> Modified ruby:
> real 0m0.010s
> user 0m0.007s
> sys 0m0.003s
>
> What do you think of the minimum optimization?


I think: if it was that easy, Matz would have done it already. But it
ain't that easy and if you want to have constant expressions simply
assign them to a constant and use that value.

I = 320 * 200 * 32

Kind regards

robert
 
Reply With Quote
 
s.ross
Guest
Posts: n/a
 
      03-28-2008
On Mar 28, 2008, at 9:19 AM, ts wrote:

> Park Heesob wrote:
>> So ruby is never fast but flexible language

>
> Well I can give you another example of "premature" optimisation, but
> for 1.9
>
> [ruby-bugs:16163]
>
>
> http://rubyforge.org/tracker/index.p...=426&atid=1698
>
> it worked but a modification was made to ruby and the optimisation
> break the code now


Before this question is relegated to the heap of "premature
optimization" ideas, I think the value of some level of programmer-
controller optimizations would be useful in the future. Optimizations
can break code so they are always "caveat programmer." Even in C,
where lots is known about the code, there are code-breaking
optimizations. Again, not a recommendation to do this; just a
recommendation not to dismiss it.

Just my $.02

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to optimize my ruby code Valentino Lun Ruby 2 11-11-2008 01:30 PM
why visual studio does not optimize constructor in this case George2 C++ 4 12-28-2007 12:44 AM
Re: why visual studio does not optimize constructor in this case Tristan Wibberley C++ 1 12-27-2007 10:53 PM
why Visual Studio can not optimize the initialization code? George2 C++ 1 12-19-2007 10:55 AM
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM



Advertisments