Why Ruby do not optimize code at all?

Discussion in 'Ruby' started by Heesob Park, Mar 28, 2008.

  1. Heesob Park

    Heesob Park Guest

    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/.
    Heesob Park, Mar 28, 2008
    #1
    1. Advertising

  2. On Fri, Mar 28, 2008 at 10:38 AM, Heesob Park <> 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
    Jason Roelofs, Mar 28, 2008
    #2
    1. Advertising

  3. On Fri, Mar 28, 2008 at 10:45 AM, Jason Roelofs <> wrote:
    >
    > On Fri, Mar 28, 2008 at 10:38 AM, Heesob Park <> 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
    Jason Roelofs, Mar 28, 2008
    #3
  4. Heesob Park

    ts Guest

    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
    ts, Mar 28, 2008
    #4
  5. 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 <>:
    > 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/.
    >
    >
    Chiyuan Zhang, Mar 28, 2008
    #5
  6. Heesob Park

    James Tucker Guest

    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 <>:
    >> 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/.
    James Tucker, Mar 28, 2008
    #6
  7. Heesob Park

    Park Heesob Guest

    SGksDQotLS0tLSBPcmlnaW5hbCBNZXNzYWdlIC0tLS0tIA0KRnJvbTogIkphc29uIFJvZWxvZnMi
    IDxqYW1lc2tpbHRvbkBnbWFpbC5jb20+DQpUbzogInJ1YnktdGFsayBNTCIgPHJ1YnktdGFsa0By
    dWJ5LWxhbmcub3JnPjsgPHJ1YnktY29yZUBydWJ5LWxhbmcub3JnPg0KU2VudDogRnJpZGF5LCBN
    YXJjaCAyOCwgMjAwOCAxMTo1MyBQTQ0KU3ViamVjdDogUmU6IFdoeSBSdWJ5IGRvIG5vdCBvcHRp
    bWl6ZSBjb2RlIGF0IGFsbD8NCg0KDQo+IE9uIEZyaSwgTWFyIDI4LCAyMDA4IGF0IDEwOjQ1IEFN
    LCBKYXNvbiBSb2Vsb2ZzIDxqYW1lc2tpbHRvbkBnbWFpbC5jb20+IHdyb3RlOg0KPj4NCi4uDQo+
    PiAgSSBndWVzcyB0aGUgZmlyc3QgcXVlc3Rpb24gaXMgZG9lcyBSdWJ5IHdpdGggeW91ciBwYXJz
    ZXIgY2hhbmdlcyBwYXNzDQo+PiAgYWxsIHRoZSB0ZXN0cz8NCj4+DQo+PiAgU2Vjb25kLCBjb3Vs
    ZCB5b3UgcG9zdCBhIHBhdGNoIGZvciBwZW9wbGUgdG8gdHJ5IG91dCBhbmQgZXZhbHVhdGU/DQo+
    PiAgV2UnbGwgbmVlZCB0byBzZWUgdGhlIGFjdHVhbCBjb2RlIHRvIHJlYWxseSBldmFsdWF0ZSBp
    ZiB5b3UndmUgZ290DQo+PiAgc29tZXRoaW5nIGhlcmUuDQo+Pg0KPj4gIEphc29uDQo+Pg0KPiAN
    Cj4gT2gsIGFuZCB0aGlzIGJlbG9uZ3MgaW4gdGhlIFJ1YnkgQ29yZSBtYWlsaW5nIGxpc3QuDQo+
    IA0KPiBKYXNvbg0KPiANCj4NCk5ldmVyIG1pbmQsIEkgZ2F2ZSBpdCB1cC4NCg0KUmVnYXJkcywN
    Cg0KUGFyayBIZWVzb2INCg==
    Park Heesob, Mar 28, 2008
    #7
  8. Heesob Park

    ts Guest

    ts, Mar 28, 2008
    #8
  9. 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
    Robert Klemme, Mar 28, 2008
    #9
  10. Heesob Park

    s.ross Guest

    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.php?func=detail&aid=16163&group_id=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
    s.ross, Mar 28, 2008
    #10
  11. On Mar 28, 11:21=A0am, "s.ross" <> wrote:
    > 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.php?func=3Ddetail&aid=3D16163&group_id=

    ...
    >
    > > 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 =A0
    > optimization" ideas, I think the value of some level of programmer-
    > controller optimizations would be useful in the future. Optimizations =A0
    > can break code so they are always "caveat programmer." Even in C, =A0
    > where lots is known about the code, there are code-breaking =A0
    > optimizations. Again, not a recommendation to do this; just a =A0
    > recommendation not to dismiss it.
    >
    > Just my $.02


    Hm, couldn't you use method_added behind the scenes somehow? Perhaps
    use the opimized parse tree unless method_added is invoked? Or cache
    the parse tree?

    Or am I talking nonsense?

    Regards,

    Dan
    Daniel Berger, Mar 28, 2008
    #11
  12. Heesob Park

    James Tucker Guest

    On 28 Mar 2008, at 21:06, Daniel Berger wrote:
    >
    >
    > On Mar 28, 11:21 am, "s.ross" <> wrote:
    >> 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.php?func=detail&aid=16163&group_id
    >>> ...

    >>
    >>> 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

    >
    > Hm, couldn't you use method_added behind the scenes somehow? Perhaps
    > use the opimized parse tree unless method_added is invoked? Or cache
    > the parse tree?
    >
    > Or am I talking nonsense?


    Probably, that would make sense for the 90th percentile of use. For
    some percentile, it'll be really bad.

    obj.extend or re-opening the class inside a method could then be a
    killer, which brings us right back to optimisation

    I guess the problem is, the people that need it, should know how to
    have the same effect on their code, those that don't just want it.
    sure it's probably not that well defined, but in seems close to the
    truth for many cases

    >
    >
    > Regards,
    >
    > Dan
    >
    James Tucker, Mar 29, 2008
    #12
  13. Heesob Park

    Eric Hodel Guest

    On Mar 28, 2008, at 08:39 AM, James Tucker wrote:
    >>> 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


    #freeze is not a solution to the constant folding optimizations. It
    only makes the object immutable, not it's class, and not its
    instance_variables, so methods may be redefined on you anyhow, and the
    contents of ivars may also change (String#replace, etc.)

    > 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.


    You can taint/untaint, but you cannot unfreeze.
    Eric Hodel, Mar 29, 2008
    #13
  14. Heesob Park

    James Tucker Guest

    On 29 Mar 2008, at 00:06, Eric Hodel wrote:
    > On Mar 28, 2008, at 08:39 AM, James Tucker wrote:
    >>>> 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

    >
    > #freeze is not a solution to the constant folding optimizations. It
    > only makes the object immutable, not it's class, and not its
    > instance_variables, so methods may be redefined on you anyhow, and
    > the contents of ivars may also change (String#replace, etc.)
    >
    >> 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.

    >
    > You can taint/untaint, but you cannot unfreeze.


    Absolutely right, never use the thing, thanks for the correction.
    James Tucker, Mar 29, 2008
    #14
  15. Heesob Park wrote:
    > 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


    The optimization is impressive. But we have to give up this kind of
    optimization for flexibility in ruby...well, it is too bad. But
    programming is really enjoying in ruby because because of its
    flexibility...and can't avoid for the tradeoff...I wonder how YARV doing
    this kind of optimization or it is not..:)
    --
    Posted via http://www.ruby-forum.com/.
    Shin guey Wong, Mar 29, 2008
    #15
  16. On Mar 28, 9:06 pm, Daniel Berger <> wrote:
    > Hm, couldn't you use method_added behind the scenes somehow? Perhaps
    > use the opimized parse tree unless method_added is invoked? Or cache
    > the parse tree?
    >
    > Or am I talking nonsense?
    >


    Not sure if method_added would be the right solution, but the
    interpreter can certainly do checks. For the new VM based Ruby
    implementations
    for example, it'd be reasonable to do JIT based optimization of it -
    it'd be relatively easy bookkeeping for the VM implementations to
    check
    for the replacement of a specific method of a specific class, and
    throw away all JIT optimized paths relying on the behavior of that
    method
    and revert to the original byte code.

    That could be done as a quite generic optimization, which pretty much
    boils down to memoization of the results of frequently occurring
    subexpressions that are known to be safe to memoize (no side effects /
    stored state etc.)

    Vidar
    Vidar Hokstad, Mar 29, 2008
    #16
  17. On 28.03.2008 18:21, s.ross wrote:

    > 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.


    I guess you mean "programmer controlled", did you? In fact, there is
    plenty of room for that today already. There are numerous techniques
    that can be applied to code to make it faster. Often, proper design and
    / or algorithms make a huge difference. :)

    Kind regards

    robert
    Robert Klemme, Mar 29, 2008
    #17
  18. Heesob Park

    s.ross Guest

    On Mar 29, 2008, at 9:50 AM, Robert Klemme wrote:

    > On 28.03.2008 18:21, s.ross wrote:
    >
    >> 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.

    >
    > I guess you mean "programmer controlled", did you? In fact, there
    > is plenty of room for that today already. There are numerous
    > techniques that can be applied to code to make it faster. Often,
    > proper design and / or algorithms make a huge difference. :)
    >
    > Kind regards
    >
    > robert


    Yes, "controlled". And yes, a good algo beats a machine optimization
    almost every time. But still, some of the stupid optimization tricks
    people have traditionally used for the last several percent destroy
    the readability of code. I've never been terribly unhappy with the
    performance of Ruby, but if I were ... say ... Industrial Light and
    Magic and choosing between Ruby and Python to glue my effects stuff
    together, I might be swayed toward Python because it preserves
    bytecode (right?). It might be nice, once we figure out how to express
    Ruby in an optimizable bytecode to create JIT optimizers that are
    platform specific. Who knows what results that might yield.

    My original point, spelling not withstanding, is that this is a topic
    (along with threading) that typically gets relegated to the premature
    optimizations bin, and doesn't rise to the level of "this should be
    possible one day and it should work with only the predictable
    glitches." If I were heavily invested in my Java or C programming
    skills, and wanted to keep Ruby out of my shop -- and there are people
    who do fight to keep new technologies away -- lack of optimization
    might be an attack plan.

    Again, just my opinion.
    s.ross, Mar 29, 2008
    #18
  19. On 29.03.2008 18:03, s.ross wrote:
    > On Mar 29, 2008, at 9:50 AM, Robert Klemme wrote:
    >
    >> On 28.03.2008 18:21, s.ross wrote:
    >>
    >>> 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.

    >> I guess you mean "programmer controlled", did you? In fact, there
    >> is plenty of room for that today already. There are numerous
    >> techniques that can be applied to code to make it faster. Often,
    >> proper design and / or algorithms make a huge difference. :)

    >
    > Yes, "controlled". And yes, a good algo beats a machine optimization
    > almost every time. But still, some of the stupid optimization tricks
    > people have traditionally used for the last several percent destroy
    > the readability of code. I've never been terribly unhappy with the
    > performance of Ruby, but if I were ... say ... Industrial Light and
    > Magic and choosing between Ruby and Python to glue my effects stuff
    > together, I might be swayed toward Python because it preserves
    > bytecode (right?).


    I am not sure what you mean by "preserve bytecode".

    > It might be nice, once we figure out how to express
    > Ruby in an optimizable bytecode to create JIT optimizers that are
    > platform specific. Who knows what results that might yield.


    There is JRuby already. IMHO this is a good way to go because a lot of
    engineering went into JVM's already and that way Ruby can benefit from
    that without having to invest the same effort into the VM.

    > My original point, spelling not withstanding, is that this is a topic
    > (along with threading) that typically gets relegated to the premature
    > optimizations bin, and doesn't rise to the level of "this should be
    > possible one day and it should work with only the predictable
    > glitches." If I were heavily invested in my Java or C programming
    > skills, and wanted to keep Ruby out of my shop -- and there are people
    > who do fight to keep new technologies away -- lack of optimization
    > might be an attack plan.


    I guess even with such optimizations Ruby will never come close in
    performance to C and maybe even not to Java because of the highly
    dynamic nature. OTOH, if explicit enabling of certain optimizations
    disables some of the dynamic features that might be ok...

    > Again, just my opinion.


    No problem with that. I just wanted to make the half serious point that
    there *is* indeed a lot of room for programmer controlled optimization
    that does not need -O3. :)

    Kind regards

    robert
    Robert Klemme, Mar 29, 2008
    #19
  20. Heesob Park

    s.ross Guest

    [Note: parts of this message were removed to make it a legal post.]

    On Mar 29, 2008, at 10:40 AM, Robert Klemme wrote:

    > I am not sure what you mean by "preserve bytecode".


    Some interpreted languages (not saying which ones :) have an option
    for preserving the pre-parsed bytecode, saving the startup parsing
    pass. This is useful for certain use-cases like Web apps or filters.
    s.ross, Mar 29, 2008
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    862
    Mark Rae
    Dec 21, 2006
  2. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,762
    Smokey Grindel
    Dec 2, 2006
  3. George2
    Replies:
    1
    Views:
    254
    Rolf Magnus
    Dec 19, 2007
  4. George2
    Replies:
    4
    Views:
    388
    Ron Natalie
    Dec 28, 2007
  5. Tristan Wibberley
    Replies:
    1
    Views:
    344
    Erik Wikström
    Dec 27, 2007
Loading...

Share This Page