interactive.com> <[EMAIL PROTECTED]>
Content-Type: text/plain; charset=US-ASCII; format=flowed
Message-Id: <[EMAIL PROTECTED]>
Content-Transfer-Encoding: 7bit
From: Stevan Little <[EMAIL PROTECTED]>
Subject: Re: [sw-design] Code and block size as complexity metrics
Date: Mon, 22 Nov 2004 11:42:46 -0500
To: practical discussion of Perl software design <[EMAIL PROTECTED]>,
Rob Kinyon <[EMAIL PROTECTED]>
X-Mailer: Apple Mail (2.619)
Rob,
I agree, opcodes will have optimizations in them which will affect the
count so they can be flawed there. And also things like assignment
statements which are one line of perl code are a lot more opcodes that
one might initially think. And again, my knowledge of perl internals
is limited to articles and papers by Simon Cozens and not hard
experience so I may be way way off course here. But my guess is that
opcode measurements might be useful when combined with other forms of
metrics. I like your idea of measuring the decision points, and in
particular their density. And Matt had a good suggestion with tokens
too.
Anyway, here is a quick script I whipped up this morning which counts
all the opcodes in a each function of a particular module.
#!/usr/bin/perl
use strict;
use warnings;
use B::Utils;
my $module = shift || die "You need to give me a module to examine\n";
my $module_to_check = $module;
if ($module_to_check =~ /\:\:/) {
$module_to_check =~ s/\:\:/\//g;
$module_to_check .= ".pm";
}
require $module_to_check;
my %ops = B::Utils::all_roots();
delete $ops{"__MAIN__"};
!/$module/ && delete $ops{$_} foreach keys %ops;
my %counts;
B::Utils::walkoptree_simple($ops{$_}, sub { $counts{$_}++ }) foreach
keys %ops;
print " num_ops | name\n";
print "-" x 50 . "\n";
foreach (sort { $counts{$a} <=> $counts{$b} } keys %ops) {
print " " . sprintf("%7d", $counts{$_}) . " | $_\n" ;
}
print "-" x 50 . "\n";
1;
I ran this on my module Tree::Simple and this is what it printed out
for me.
num_ops | name
--------------------------------------------------
18 | Tree::Simple::getWidth
18 | Tree::Simple::height
18 | Tree::Simple::getDepth
18 | Tree::Simple::getHeight
18 | Tree::Simple::getParent
18 | Tree::Simple::getNodeValue
18 | Tree::Simple::getUID
20 | Tree::Simple::fixDepth
22 | Tree::Simple::getChildCount
24 | Tree::Simple::isLeaf
26 | Tree::Simple::setUID
27 | Tree::Simple::setNodeValue
28 | Tree::Simple::getAllChildren
28 | Tree::Simple::isRoot
30 | Tree::Simple::getAllSiblings
30 | Tree::Simple::getChild
32 | Tree::Simple::getSibling
32 | Tree::Simple::insertSibling
32 | Tree::Simple::addSiblings
32 | Tree::Simple::addSibling
32 | Tree::Simple::insertSiblings
34 | Tree::Simple::addChildren
41 | Tree::Simple::size
44 | Tree::Simple::accept
46 | Tree::Simple::cloneShallow
48 | Tree::Simple::new
56 | Tree::Simple::_setHeight
58 | Tree::Simple::traverse
60 | Tree::Simple::fixWidth
61 | Tree::Simple::getIndex
62 | Tree::Simple::_setWidth
63 | Tree::Simple::clone
66 | Tree::Simple::DESTROY
73 | Tree::Simple::addChild
75 | Tree::Simple::_setParent
91 | Tree::Simple::fixHeight
100 | Tree::Simple::removeChild
143 | Tree::Simple::_init
183 | Tree::Simple::insertChild
183 | Tree::Simple::insertChildren
195 | Tree::Simple::removeChildAt
223 | Tree::Simple::_cloneNode
--------------------------------------------------
It actually pretty accurately reflects the "size" of each
method/function in the module, although somethings are a little skewed.
For instance the method Tree::Simple::insertChild is just an alias to
Tree::Simple::insertChildren (*insertChild = \&insertChildren) so the
weight of those is somewhat inaccurate, and in some ways very accurate.
And take the first 7 methods listed (all 18 opcodes), each of those is
a basic accessor function, all written pretty uniformly. This gets
reflected in the counts, which (at least to me) is pretty interesting.
Okay, back to work now :)
Steve
On Nov 22, 2004, at 8:49 AM, Rob Kinyon wrote:
> I don't like this entire opcode thing for evaluating code quality. To
> me, they are measuring two different things. Opcode quality is an
> optimization issue. Code quality is a human issue.
>
> Now, I think you can provide a set of tools that measures them both
> (plus more), but I don't think you measure code quality from the
> opcodes.
>
> Rob
>
> (Plus, an opcode isn't really a single atomic operation like you might
> think. Some opcodes are much heavier than others.)
>
> (Also, some opcodes are much lighter than others, such as the NOOP.)
>
> On Sun, 21 Nov 2004 23:51:24 -0500, Stevan Little
> <[EMAIL PROTECTED]> wrote:
>> Matt,
>>
>>
>>
>> On Nov 21, 2004, at 10:42 PM, Matt Olson wrote:
>>> On Sun, 21 Nov 2004 22:16:25 -0500, Rob Kinyon <[EMAIL PROTECTED]>
>>> wrote:
>>>> Some thoughts (in no particular order):
>>>> 1) Look at statements, not LOC. Otherwise, you start unfairly
>>>> penalizing people who uncuddle their elses.
>>>
>>> I like Kernighan & Pike's metric (in The Practice of Programming): my
>>> copy's at home, but IIRC they count tokens, rather than statements or
>>> LOC, when comparing languages.
>>
>> Thats why i was thinking we could count perl opcodes. I would think
>> they would be a great way to tell the actual "size" of a given block
>> of
>> code. But then again, tokens is not bad either and the PPI project
>> (http://search.cpan.org/~adamk/PPI/) already has a high quality Perl
>> Tokenizer available.
>>
>>> Incidentally, I strongly recommend TPoP as a "practical software
>>> engineering" book.
>>
>> Been on my Amazon to-buy forever actually.
>>
>> Steve
>>
>>
>>
>>>
>>> --Matt
>>>
>>> _______________________________________________
>>> sw-design mailing list
>>> [EMAIL PROTECTED]
>>> http://metaperl.com/cgi-bin/mailman/listinfo/sw-design
>>>
>>
>> _______________________________________________
>> sw-design mailing list
>> [EMAIL PROTECTED]
>> http://metaperl.com/cgi-bin/mailman/listinfo/sw-design
>>
>
> _______________________________________________
> sw-design mailing list
> [EMAIL PROTECTED]
> http://metaperl.com/cgi-bin/mailman/listinfo/sw-design
>
_______________________________________________
sw-design mailing list
[EMAIL PROTECTED]
http://metaperl.com/cgi-bin/mailman/listinfo/sw-design