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

Reply via email to