単項メッセージの使用頻度


System.exit() の「メソッドの使用頻度の統計」に触発されて…。


札幌市にお住まいの○○さんからのお便りです。「Smalltalk システムって、クラスライブラリはもちろん、言語処理系自体がほぼすべて Smalltalk 言語で記述されていて、ソースもエンドユーザーが容易にたぐれるし、そこでどんなメッセージが送信されているかってのもすぐわかるじゃないですか。ヒューメイン・インターフェイス的なメッセージっていったいどのくらい使われているかも簡単に調べられそうですよね。これってトリビアになりませんか?」

このトリビアの種、つまりこういうことになります。「Smalltalk システムでもっともよく使われる単項メッセージは プギャー 」


実際に調べてみた…。Smalltalk システムとしては、ANSI 準拠のものや正統派 VisualWorks は少々ストイックに過ぎるので、冗長さ、奔放さでは他に類を見ない Squeak システムを使用。調査に用いたスクリプトは次のようなものです(“Everything is an object”and/or リフレクションの強力さが自慢の Ruby 他の言語でも、こう簡単にはいきますまい。ふっふっふ…)。結果出力は上位 100 位まで。メソッド名のカウント方法については CompiledMethod >> #messages を パクリ 参考にしました。

| bag |
bag := Bag new.
SystemNavigation default allBehaviorsDo: [:class |
   class methodsDo: [:method |
      | scanner |
      scanner := InstructionStream on: method.
      scanner scanFor: [:instr | scanner addSelectorTo: bag. false]]].
^ (bag select: [:each | each numArgs isZero]) sortedCounts first: 100


せっかくなのでプログレスバーを表示するヒューメイン・インターフェイス(?)版も。

| bag navi numOfClasses count |
bag := Bag new.
navi := SystemNavigation default.
numOfClasses := 0.
count := 0.
navi allBehaviorsDo: [:class | numOfClasses := numOfClasses + 1].
'summing selectors up...'
   displayProgressAt: Sensor cursorPoint from: 0 to: numOfClasses
   during: [:bar |
      navi allBehaviorsDo: [:class |
      bar value: (count := count + 1).
      class methodsDo: [:method |
         | scanner |
         scanner := InstructionStream on: method.
         scanner scanFor: [:instr | scanner addSelectorTo: bag. false]]]].
^ (bag select: [:each | each numArgs isZero]) sortedCounts first: 100

やっていることはいずれも同じです。プログレスバーの出し方については、#do:displayingProgress: が使えないので、似たようなことをしている SystemDictionary >> #abandonSources のを パクリ 参考にしました。


2位以降の結果。

4907->#size
2263->#translated
2196->#first
2116->#class
1883->#cr
1458->#name
1397->#x
1375->#y
1239->#printString
1194->#asString
1151->#isNil
1117->#not
1067->#extent
1022->#isEmpty
 949->#last
 918->#position
 895->#value
 872->#notNil
 836->#next
 833->#contents
 807->#width
 784->#height
 694->#second
 682->#copy
 674->#primitiveFail
 610->#negated
 610->#initialize
 606->#asFloat
 574->#current
 555->#default
 533->#asInteger
 527->#asSymbol
 522->#world
 519->#bounds
 513->#close
 499->#origin
 492->#delete
 487->#cursorPoint
 473->#space
 464->#key
 458->#transparent
 455->#top
 452->#topLeft
 442->#depth
 422->#asArray
 421->#boundingBox
 420->#black
 406->#failed
 390->#center
 386->#changed
 379->#yourself
 378->#hand
 371->#atEnd
 368->#submorphs
 360->#reset
 346->#left
 343->#tab
 319->#addLine
 313->#bottom
 308->#asciiValue
 295->#costume
 291->#rounded
 279->#primitiveFailed
 277->#red
 275->#selector
 275->#white
 275->#third
 272->#owner
 254->#truncated
 254->#braceArray
 253->#subclassResponsibility
 252->#color
 243->#asLowercase
 243->#asText
 241->#receiver
 235->#wait
 232->#fullBounds
 226->#abs
 225->#millisecondClockValue
 224->#right
 217->#text
 216->#copyBits
 214->#asNumber
 209->#over
 208->#isMorphic
 204->#blue
 203->#renderedMorph
 202->#isEmptyOrNil
 192->#binary
 187->#string
 185->#basicNew
 173->#organization
 173->#hash
 171->#beep
 171->#basicSize
 166->#layoutChanged
 165->#currentWorld
 164->#selectedClassOrMetaClass
 162->#systemNavigation

残念(?)ながら #isZero はここでは圏外。でも、#first や #second、 #last、それに、#isEmpty、#atEnd、#isNil、#notNil などは冗長な表現でありながら比較的よく使われているようですね。


そして、1位は…

7068->#new


そりゃそーだ…。orz