habit_forming has asked for the wisdom of the Perl Monks concerning the following question:

Oh great and powerful Monks... I am confused. I have a large-ish piece of code that modifies several packages by redefining a few of their subs. Other than that it is fairly normal piece of code. My question is this: When and for what reasons could MyModule::BEGIN be called. I just profiled this piece of code and apparently the MyModule::BEGIN statement is called ~74 times! If at all possible, I would like to reduce that number. Near 20% of the total run-time of the program is being spent there.

Cheers!
--habit

Replies are listed 'Best First'.
Re: MyModule::BEGIN calls
by duff (Parson) on Dec 08, 2003 at 19:29 UTC

    Normally BEGIN routines are called immediately after they are parsed and then discarded. Do you have 74 BEGIN routines? Do you create BEGIN routines in your program with eval?

    Are you sure you're reading your profile data correctly?

      Thank you for your response.

      Many of the MyModule::BEGIN come directly before a constant::import or Exporter::import or some other *::import. It is because the module (which I did not write) uses many, many constants in its implementation that it has to be re-parsed? I am, of course, assuming that A BEGIN involves some kind of reparse, during the compile-execute loop.

      No, do not "create" BEGINs inside an eval. But I do have a "use" in inside of one eval. I understand that a use is a BEGIN but I was sure to not to have any variables and to use the eval { }; not the eval " "; form.

      --habit

        There's not a reparse, but a single parse. While perl is parsing your source file, as soon as it finishes parsing a BEGIN routine, it executes it immediately before continuing to parse the rest of the code.

        the module ... uses many, many constants in its implementation

        Sounds like you could take advantage of use constant, see constant.

        Count how many BEGIN routines you have in your source. I bet it's ~74. If your program really is spending 20% of its run time executing those BEGIN routines, then you need to decide if that's an important 20% or not. :-) If it is, then maybe you could gain some advantage by coelescing the BEGIN routines or converting them to some other form

Re: MyModule::BEGIN calls
by habit_forming (Monk) on Dec 08, 2003 at 20:59 UTC
    Ok here is an update.

    MyModule has 50-60 use constant's. If I change those to *CONST1 = sub {42};. The massive number of MyModule::BEGINs drops dramatically and thus saves a heck of a lot of time.
    But still sometimes changing a use constant to a *C = sub { ... } does not work. Anyone have any ideas on that?

    --habit

    P.S. I think it may have to do with the way things are exported...

      Why 50-60? Why not just one big, ugly, use constant declaration near the beginning?

Re: MyModule::BEGIN calls
by Zed_Lopez (Chaplain) on Dec 08, 2003 at 19:36 UTC

    Lemme guess... you use MyModule 74 times. BEGIN blocks are called for one very well defined reason: the module is parsed (prior even to completing compilation.)

    Updated: Never mind; see integral's correction, below.

      BEGIN blocks are called during compilation, since use internally uses the same mechanisms as require, modules are only loaded once. This means that top-level code and BEGIN blocks in the module are only executed once. This means that even 74 use MyModule statements aren't going to run those BEGIN blocks more than once.

      --
      integral