Optimize debugging subs
danb
created: 2006-04-04 23:20:04
Is it possible to optimize debugging subs into no-ops at compile time? I already know one method of doing so, but it's inelegant:
sub ENABLE_DEBUG () { 0 }
sub debug { print $_[0]; }
debug 'test' if ENABLE_DEBUG;
You can see the call gets optimized away in the Deparse output:
sub ENABLE_DEBUG () { 0 }
sub debug {
    print $_[0];
}
'???';
However, the more elegant equivalent...
sub ENABLE_DEBUG () { 0 }
sub debug { print $_[0] if ENABLE_DEBUG; }
debug 'test';
...does not get optimized away:
sub ENABLE_DEBUG () { 0 }
sub debug {
    0;
}
debug 'test';

--Dan

Re: Optimize debugging subs
created: 2006-04-04 23:29:38
danb--

Perhaps a compromise based on something like the following attempt? (Disclaimer: I've not tried this, nor have I ever used Deparse...)

use constant DBG => 0;

  . . .

DBG && print "Any debugging statement\n";
If it works, it has the advantage that you can use a larger range of debug helper type statements after the && operator...

--roboticus

Re^2: Optimize debugging subs
created: 2006-04-05 00:24:05
Thanks for the suggestion, that is just as inelegant.

--Dan

Re: Optimize debugging subs
created: 2006-04-04 23:34:25
Your more elegant equivalent achives the same leval of optimization, print $_[0] if ENABLE_DEBUG; evaluates to false.
Re^2: Optimize debugging subs
created: 2006-04-05 00:20:58
This benchmark indicates that you are wrong.
sub ENABLE_DEBUG () { 0 }
sub debug_inelegant { print $_[0]; }
sub debug_elegant { print $_[0] if ENABLE_DEBUG; }

use Benchmark qw(:all) ;

cmpthese( 30000000, 
    { 
        'inelegant' => "debug_inelegant 'test' if ENABLE_DEBUG;",
        'elegant'   => "debug_elegant 'test';"
    },
);

Output:
                Rate   elegant inelegant
elegant    3337041/s        --      -95%
inelegant 62500000/s     1773%        --

--Dan

Re^3: Optimize debugging subs
created: 2006-04-05 01:07:14
By your benchmark, elegant takes 0.0000003 seconds (0.3 microseconds) to execute. What's the problem?
Re^4: Optimize debugging subs
created: 2006-04-05 02:10:19

Good point; what about this?

Lots debug() calls inside a long-running loop, inside many very frequently called subs, running in a virtual server program (with access to only 10% of the CPU), running on a commodity server (Pentium-III 1.3 Ghz), being accessed by many simultaneous clients.

That's a lot different than the Benchmark I just ran on a Athlon64 X2 2.4ghz.

Besides, what about the enjoyment of knowing that there is *no* debugging code in your program?

--Dan

Re^5: Optimize debugging subs
created: 2006-04-05 10:22:31
Besides, what about the enjoyment of knowing that there is *no* debugging code in your program?

Enjoyment? In practice, I've found debug vs production optimizations a source of headaches.

Also in practice, I've found the production version is not sufficiently tested. People assume the production version will work because the debug version does.

Re: Optimize debugging subs
created: 2006-04-05 00:21:38

You'd want to prefer use constant to sub ... () { ... }. Perl core keeps constant more up to date with what's right for the version that's running your perl than your code will ever be. For instance, the 5.9.3+ version is best expressed in a manner *other* than a simple sub ... () { ...}. If you use constant, perl will do the right thing for the perl version you're using. If you're doing it by hand, you may be doing it suboptimally.

⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Re: Optimize debugging subs
created: 2006-04-05 01:13:49
A (non-portable) option is to invoke CPP by using -P, as documented in [doc://perlrun].
#!/usr/bin/perl -P

sub ENABLE_DEBUG () { 0 }

sub _debug { print $_[0]; }
#define debug(s) _debug(s) if ENABLE_DEBUG

debug("test\n");

perlmonks.org content © perlmonks.org and Anonymous Monk, danb, diotalevi, ikegami, roboticus

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03