Boost logo

Boost :

From: joel de guzman (djowel_at_[hidden])
Date: 2002-03-21 21:59:51


----- Original Message -----
From: "Jaakko Jarvi"
 
> The performance difference probably stems from the fact that phoenix
> constructs a tuple out of the arguments, which the g++ cannot
> optimize away. LL does not store the arguments to lambda functors into
> any intermediate objects, but rather just passes them unchanged to
> the underlying functions.

The intermediate tuple is very important for extensibility. For example
the tuple can be extended to provide local variables (contexts and scopes).
Here's a snipet from sample8.cpp:

    for_each(c.begin(), c.end(),
        locals<int, char const*>(0, "...That's all\n")
        [
            for_(loc1 = 0, loc1 < arg1, ++loc1)
            [
                cout << loc1 << ", "
            ],
            cout << loc2
        ]
    );

locN are local variables.
And another example from sample10.cpp that pushes the idea more:

    int _10 = 10;

    context<nil_t>
    (
        1000, // lvar1: local int variable
        cout << arg1 << '\n', // lfun2: local function w/ 1 argument (arg1)
        lvar1 * 2, // lfun3: local function that accesses local variable lvar1
        lfun2(2 * arg1) // lfun4: local function that calls local function lfun2
    )
    [
        lfun2(arg1 + 2000),
        lfun2(val(5000) * 2),
        lfun2(lvar1 + lfun3()),
        lfun4(55),
        cout << lvar1 << '\n',
        cout << lfun3() << '\n',
        cout << val("bye bye\n")
    ]

    (_10);

lfunN are local functions!
Also, the intermediate tuple makes it simpler to support N arity
(3~15 in the current version of Phoenix).

This same technique when applied to Spirit can do away with
virtual functions and place-holders by making a whole grammar
a single expression. Here's an experimental *working* grammar
http://home.JCABs-Rumblings.com/ftp/new_spirit.cpp
(Notice the recursive rule invocations)

    rule_id<0> expression;
    rule_id<1> term;
    rule_id<2> factor;

    return (

        factor = digit_p
                    | '(' >> expression >> ')'
                    | ('-' >> factor)
                    ,

        term = factor >>
                    *( ('*' >> factor)
                    | ('/' >> factor)
                    )
                    ,

        expression = term >>
                    *( ('+' >> term)
                    | ('-' >> term)
                    )

    ).parse(parg);

>
> KCC can optimize the tuples away.

Thanks for being balanced :-)

--Joel


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk