challenge 関数やメソッドのソースの平均行数

イントロスペクションおよびメトリックスのお題です。

アジャイル界隈などでは、あまり長くだらだらと書いてはいけない…と言われている 関数 and/or メソッド ですが、ならば実際のところ、洗練された既存のライブラリにおいて、関数 and/or メソッド は平均すると何行くらいで記述されているのか…といった情報を具体的に把握しておきたいと思ったことはありませんか?

そこで、みなさんイチオシの言語それ自身で書かれているライブラリを、それなりの規模になるように集めてきて、1)集めたライブラリ群内に定義されている全 関数 and/or メソッド の合計数(母集団の確認のため)、と 2)関数 or メソッドのソースの平均の行数、を求めるコードと、その結果を示してください。

なお、関数 and/or メソッドに帰属するものであれば、コメント行やアノテーションのたぐいも行数のカウントに含めてください(コードが必要以上に複雑にならない範囲で結構です)。また、関数内関数定義やメソッド内クラス定義(ひいてはその中でのメソッド定義)といった入れ子になったコードの行数をどう解釈するかの判断はお任せします。関数とメソッドが共存する言語では両者を区別してカウントする必要はありません(しても構いません)。平均値を求めるコードを、対象言語で記述することが技術的に困難な場合は、UNIX的なツールを組み合わせたり、IDEなどが提供するメトリックス機能を活用して算出した結果を示すのでもよいと思います。

このお題は、平均行数が 8.4 行(Squeak Smalltalk の組み込みライブラリ+αより、調査メソッド総数 4万)と、一般に簡潔さが美徳とされている Smalltalk からの挑戦(?)でもあります。

Posted feedbacks - Nested

Flatten Hidden

Squeak Smalltalk で。

Smalltalk ではメソッドもオブジェクトで、そのソースはメソッドオブジェクト(CompiledMethod のインスタンス)の属性であるかのような扱いになっています。したがって、各メソッドに問い合わせ(getSource)て得られたソースコードの行数(lineCount)を列挙し、その平均(average)を出せば、今回調べたい平均行数が求まります。

1
2
3
4
5
| numsOfLines |
numsOfLines := CompiledMethod allInstances collect: [:each | each getSource lineCount].
^{#調査メソッド総数-> numsOfLines size. #平均行数 -> numsOfLines average asFloat}

"=>{#調査メソッド総数->42237 . #平均行数->8.37561853351327} "
 新年明けましておめでとうございます。
 最初は頑張ってC言語で作れないかやってみたのですが、関数名にマクロが
使われている等の理由で8割程度しか把握できませんでした。仕方がないのでVS2008
のマクロ機能を使ってやってみました。

 対象は、"C:\Program Files\Microsoft Visual Studio 9.0\VC\crt\src"にあった
拡張子が"*.c"のファイル全てです。空のプロジェクトを作成し、これらのファイルを
ソースファイルとして取り込んでから、このマクロを実行すると結果が表示されます。

 一応、VC++で使われているC言語ソースという限定的な条件ですが...

<調査対象のファイル>
_ctype.c
_filbuf.c
_file.c
_filwbuf.c
_flsbuf.c
_flswbuf.c
...

<調査対象の関数>
_Getcvt: 9
_Wcrtomb: 54
__Wcrtomb_lk: 10
__iscsym: 6
_iscsym_l: 7
__iscsymf: 6
_iscsymf_l: 7
...

<結果>
調査ファイル総数: 708
調査関数総数: 1359
平均行数: 36.3951434878587
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
Imports Microsoft.VisualStudio.VCCodeModel

Public Module CFunctionEnumeration
    Dim numberOfFiles As Integer
    Dim numberOfFunctions As Integer
    Dim totalLines As Integer

    ' 色々と処理が面倒なので例外にしてしまった。
    Private Class OutputPainNotExistException
        Inherits Exception

        Public Sub New(ByVal message As String)
            MyBase.New(message)
        End Sub
    End Class

    Private Function GetOutputPane() As OutputWindowPane
        ' 結果を表示するペインを作成して返す。
        Const titleOfPain As String = "関数調査の結果"
        Static Dim isPainCreated As Boolean = False
        Dim pains As OutputWindowPanes = DTE.ToolWindows.OutputWindow.OutputWindowPanes

        If isPainCreated = False Then
            For Each p As OutputWindowPane In pains
                If p.Name = titleOfPain Then
                    GoTo ALREADY_CREATED
                End If
            Next

            If pains.Add(titleOfPain) Is Nothing Then
                Throw New OutputPainNotExistException(titleOfPain & "ペインは存在しません。")
            End If

ALREADY_CREATED:
            isPainCreated = True
        End If

        GetOutputPane = pains.Item(titleOfPain)
    End Function

    Private Sub OutputString(ByRef s As String)
        GetOutputPane().OutputString(s)
    End Sub

    Private Sub OutputSourceFiles()
        ' ソースファイル名を出力する。
        Dim projectFolders As ProjectItems = DTE.Solution.Item(1).ProjectItems

        For Each i As ProjectItem In projectFolders
            If i.Name = "ソース ファイル" Then
                Dim sourceFileFolder As ProjectItems = i.ProjectItems

                For Each j As ProjectItem In sourceFileFolder
                    OutputString(j.Name & vbCrLf)
                    numberOfFiles = numberOfFiles + 1
                Next
            End If
        Next
    End Sub

    Private Sub OutputFunctions()
        ' 関数名とソースコードの行数を出力する。
        Dim codeModel As VCCodeModel = DTE.Solution.Item(1).CodeModel

        For Each f As VCCodeFunction In codeModel.Functions
            Dim lines As Integer = f.EndPoint.Line() - f.StartPoint.Line() + 1

            OutputString(f.Name & ": ")
            OutputString(lines & vbCrLf)
            numberOfFunctions = numberOfFunctions + 1
            totalLines = totalLines + lines
        Next
    End Sub

    Private Sub OutputResult()
        OutputString("調査ファイル総数: " & numberOfFiles & vbCrLf)
        OutputString("調査関数総数: " & numberOfFunctions & vbCrLf)
        OutputString("平均行数: " & (CDbl(totalLines) / numberOfFunctions) & vbCrLf)

    End Sub

    Private Sub Reset()
        numberOfFiles = 0
        numberOfFunctions = 0
        totalLines = 0
    End Sub

    Public Sub OutputFunctionLength()
        Try
            Dim p As OutputWindowPane = GetOutputPane()

            Reset()
            p.Clear()
            OutputString("<調査対象のファイル>" & vbCrLf)
            OutputSourceFiles()
            OutputString(vbCrLf)
            OutputString("<調査対象の関数>" & vbCrLf)
            OutputFunctions()
            OutputString(vbCrLf)
            OutputString("<結果>" & vbCrLf)
            OutputResult()
            p.Activate()
        Catch e As Exception
            MsgBox(e.Message, MsgBoxStyle.Critical)
        End Try
    End Sub
End Module
補足で、VSに理解できないように関数が記述されている場合は含まれません。あと、paneが痛いになってました...orz

Index

Feed

Other

Link

Pathtraq

loading...