メソッド数の多い組み込みクラスを列挙
ああ…、ごめんなさい。大事な但し書きを忘れました。orz
可能であれば、継承したメソッド数は含まずに、そのクラスで定義(再定義も含む)されたメソッド数のみをカウントしてください。
言語処理系ごとに、普段目にするクラス群において、最大、どのくらいのメソッドを定義したクラスが存在するのか(心情的に許容されるのか)を知りたかったのですが、継承されたメソッドを含めてしまうと、階層が深くなるほどメソッド数が多くなる当たり前の傾向を見るだけになってしまうので…
おなじ理由で、メタクラスを持たない言語では、static メソッドについてもカウントから除いてください。もし数える場合でも別物としてカウントしてください(SomeClass -> 15, SomeClass static -> 5 というように)。
おそらく、わざわざ static メソッドだけ個別にカウントせずとも、省いてしまっても結果には影響しないだろうと思われます(static メソッド数が上位10番に入るほど多く定義されているクラスは存在しないと予想されるので)。
Posted feedbacks - Flatten
Nested Hidden「言語処理系に組み込みの全クラス」が、.NET Frameworkのどこまでに該当するかが分からなかったので、そのプロジェクトで参照されている全クラスを対象としました。
以下の実行結果は、普通にWindowsApplicationのプロジェクトを作ると参照されているものだけが対象になっています。参照するアセンブリを増やせば、結果が変わってくると思います。
以下、実行結果:
System.Convert: 314 System.Reflection.Emit.TypeBuilder: 170 System.Runtime.InteropServices.Marshal: 156 System.Type: 146 System.Reflection.Emit.EnumBuilder: 135 System.Net.Sockets.Socket: 135 System.Reflection.Emit.GenericTypeParameterBuilder: 134 System.RuntimeType: 131 System.ReflectionOnlyType: 131 System.Reflection.TypeDelegator: 129 System.Reflection.Emit.SymbolType: 129 System.Reflection.Emit.TypeBuilderInstantiation: 129 全クラス数: 4295
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 | using System;
using System.Collections.Generic;
using System.Reflection;
namespace Doukaku270 {
class Program {
static void Main(string[] args) {
int classCount = 0;
SortedDictionary<int, List<Type>> result = new SortedDictionary<int, List<Type>>();
foreach (AssemblyName name in typeof(Program).Assembly.GetReferencedAssemblies()) {
Assembly asm = Assembly.Load(name);
if (asm != null) {
foreach (Type type in asm.GetTypes()) {
int methodCount = type.GetMethods().Length;
if (!result.ContainsKey(methodCount)) {
result[methodCount] = new List<Type>();
}
result[methodCount].Add(type);
classCount++;
}
}
}
List<int> keyList = new List<int>(result.Keys);
keyList.Reverse();
int count = 0;
foreach (int key in keyList.GetRange(0, 10)) {
foreach (Type type in result[key]) {
Console.WriteLine("{0}: {1}", type.FullName, key);
count++;
}
if (count >= 10)
break;
}
Console.WriteLine("全クラス数: {0}", classCount);
}
}
}
|
メソッド数はそのクラスが持つpublicメソッドの数で、継承されたものを含みます。
結果は以下の通り
javax.swing.JMenuItem : 407
javax.swing.JPasswordField : 407
javax.swing.text.html.FrameView$FrameEditorPane : 408
javax.swing.JEditorPane : 408
javax.swing.JCheckBoxMenuItem : 409
javax.swing.JFormattedTextField : 412
javax.swing.JTextPane : 422
javax.swing.JMenu : 433
javax.swing.JTree : 437
javax.swing.JTable : 456
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 | package doukaku;
import java.io.File;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.jar.*;
public class HugeClasses {
public static void main(String[] args) throws Exception {
final File rt = new File(System.getProperty("java.home"), "lib/rt.jar");
if (!rt.exists()) {
System.err.println("rt.jarが見つかりません。");
return;
}
final int topN = 10;
NavigableSet<ClassHolder> sortSet = new TreeSet<ClassHolder>();
for (JarEntry entry : Collections.list(new JarFile(rt).entries())) {
String name = entry.getName();
if ((name.startsWith("java/") || name.startsWith("javax/"))
&& name.endsWith(".class")) {
String className = name.substring(0, name.length() - 6)
.replace('/', '.');
Class<?> clazz = Class.forName(className);
sortSet.add(new ClassHolder(clazz));
if (sortSet.size() > topN) sortSet.pollFirst();
}
}
for (ClassHolder classHolder : sortSet) {
System.out.printf("%-60s: %d%n", classHolder.className,
classHolder.methodCount);
}
}
private static class ClassHolder implements Comparable<ClassHolder> {
private static final AtomicInteger idCounter = new AtomicInteger(0);
private String className;
private int methodCount;
private int id;
ClassHolder(Class<?> clazz) {
id = idCounter.getAndIncrement();
className = clazz.getName();
methodCount = clazz.getMethods().length;
}
@Override
public int compareTo(ClassHolder o) {
return methodCount != o.methodCount ?
methodCount - o.methodCount
: id - o.id;
}
}
}
|
ああ…、ごめんなさい。大事な但し書きを忘れました。orz
可能であれば、継承したメソッド数は含まずに、そのクラスで定義(再定義も含む)されたメソッド数のみをカウントしてください。
言語処理系ごとに、普段目にするクラス群において、最大、どのくらいのメソッドを定義したクラスが存在するのか(心情的に許容されるのか)を知りたかったのですが、継承されたメソッドを含めてしまうと、階層が深くなるほどメソッド数が多くなる当たり前の傾向を見るだけになってしまうので…
私もhoriuchiさんと同じく、プロジェクトの参照しているアセンブリのみ対象として実施しました。 ワンライナー狙って見ましたが、やりすぎ感があったので、途中コードもコメントで残しておきました。 horiuchiさんとの差異については以下の部分かな?とか。 ■コード BindingFlagを使ってprivateも参照してる # このフラグで合ってるはずですが・・・ ■環境 Visual Studio 2010beta .NET Framework 4.0
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 | //全クラス数 : 3634
//System.Linq.Expressions.Expression : 387
//System.Convert : 313
//System.Linq.ParallelEnumerable : 210
//System.Runtime.InteropServices.Marshal : 203
//System.Linq.Enumerable : 203
//Microsoft.Win32.Win32Native : 199
//System.Linq.Expressions.Strings : 180
//System.Linq.Expressions.Error : 146
//System.Linq.Queryable : 124
//System.Console : 117
using System;
using System.Linq;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
//var classTypes = typeof(Program).Assembly.GetReferencedAssemblies().Select(assemblyName => Assembly.Load(assemblyName).GetTypes()).SelectMany(classType => classType);
//var classCountDict = classTypes.ToDictionary(classType => classType, classType => classType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly).Count());
//var result = classCountDict.OrderByDescending(pair => pair.Value).Take(10);
var classCountDict = typeof(Program).Assembly.GetReferencedAssemblies().Select(assemblyName => Assembly.Load(assemblyName).GetTypes()).SelectMany(classType => classType).ToDictionary(classType => classType, classType => classType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly).Count());
Console.WriteLine("全クラス数 : {0}", classCountDict.Keys.Count());
foreach (var obj in classCountDict.OrderByDescending(pair => pair.Value).Take(10))
{
Console.WriteLine("{0} : {1}", obj.Key, obj.Value);
}
Console.ReadLine();
}
}
|
おなじ理由で、メタクラスを持たない言語では、static メソッドについてもカウントから除いてください。もし数える場合でも別物としてカウントしてください(SomeClass -> 15, SomeClass static -> 5 というように)。
おそらく、わざわざ static メソッドだけ個別にカウントせずとも、省いてしまっても結果には影響しないだろうと思われます(static メソッド数が上位10番に入るほど多く定義されているクラスは存在しないと予想されるので)。
Squeak Smalltalk で。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | | clsCount result |
clsCount := 0.
result := Dictionary new.
SystemNavigation default allBehaviorsDo: [:class |
clsCount := clsCount + 1.
result at: class put: class selectors size].
^{#全クラス数 -> clsCount. (result associations sort: [:a :b | a value > b value]) first: 10}
"=> {#全クラス数 -> 4384. {
Morph -> 1165.
Player -> 620.
PasteUpMorph -> 469.
Preferences class -> 450.
Object -> 436.
ParagraphEditor -> 284.
SyntaxMorph -> 250.
Behavior -> 243.
ScriptLoader -> 236.
String -> 233
}} "
|
何もuseしない場合のpackageとそこに定義されてるsubをSTASHから拾ってきて数えてます。
手元の環境(v5.10.0 built for MSWin32-x86-multi-thread) では
main::Win32 --- 21 main::version --- 16 Tie::Hash::NamedCapture --- 9 main::mro --- 9 main::utf8 --- 8 main::Internals --- 6 main::re --- 4 main::UNIVERSAL --- 4 PerlIO::Layer --- 2 main::DynaLoader --- 1
という結果になりました
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 | my %cnt;
my $top = '*main::';
count_subs($top,\%cnt);
--$cnt{$top}; # sub count_subs の分を差し引く
my $i=0;
$\="\n";
print for map { "@{[substr($_->[0],1,-2)]} --- $_->[1]" }
grep { ++$i <= 10 }
sort {$b->[1] <=> $a->[1]}
map { [$_, $cnt{$_}] } keys %cnt;
my %counted;
sub count_subs
{
my ($mod, $cnt) = @_;
return if exists $cnt->{$mod};
$cnt->{$mod} = 0;
return if !defined %{$mod};
while (my ($k,$v) = each %{$mod}) {
if ( substr($k, -2) eq '::' ) {
count_subs($v, \%cnt);
}
elsif (defined &{$v} && !exists $counted{$v}) {
++$cnt->{$mod};
$counted{$v}=undef;
}
}
}
|
もっといい方法がありそうな気がします。 $ gosh doukaku270.scm <top> : 36 <class> : 17 <generic> : 7 <list> : 7 <integer> : 7 <method> : 5 <symbol> : 5 <string> : 5 <regmatch> : 4 <object> : 4 $
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 | (use srfi-1)
(define *builtin-identifiers*
(let1 module (find-module 'gauche)
(filter-map
(cut global-variable-ref module <> #f)
(remove (cut eq? '~$ <>)
(hash-table-map (module-table module)
(lambda (sym _) sym))))))
(define *builtin-classes*
(filter (cut is-a? <> <class>) *builtin-identifiers*))
(define *builtin-generic-functions*
(filter (cut is-a? <> <generic>) *builtin-identifiers*))
(define (direct-methods class)
(filter-map (lambda (method)
(let1 specs (slot-ref method 'specializers)
(and (member class specs)
method)))
(append-map (cut slot-ref <> 'methods)
*builtin-generic-functions*)))
(define (main args)
(for-each
(lambda (x) (format #t "~10a : ~2d~%" (class-name (car x)) (cdr x)))
(take (sort-by (map (lambda (class)
(cons class (length (direct-methods class))))
*builtin-classes*)
cdr
>)
10))
0)
|
パッケージごとに、関数定義をもつシンボルの個数を数えました。他のパッケージから継承したシンボルは含めていません。
CLISP 2.38 で動かしてみた結果:
SYSTEM : 1394 COMMON-LISP : 755 CS-COMMON-LISP : 752 CLOS : 647 EXT : 503 POSIX : 147 FFI : 127 I18N : 63 GRAY : 31 EXPORTING : 28
1 2 3 4 5 6 | (loop for p in (list-all-packages) collect
(list (package-name p)
(loop for s being each present-symbol in p count (fboundp s)))
into x
finally (format t "~10{~{~15A : ~A~}~%~}~%"
(sort x #'> :key #'cadr)))
|
Mac OS X 10.4.11 の java 1.5.0_19 で実行した結果は以下です。
com.sun.corba.se.impl.logging.ORBUtilSystemException -> 1248
com.sun.corba.se.impl.logging.OMGSystemException -> 524
com.sun.corba.se.impl.logging.POASystemException -> 284
java.awt.Component -> 277
org.w3c.dom.css.CSS2Properties -> 244
com.sun.rowset.CachedRowSetImpl -> 211
com.sun.rowset.internal.SyncResolverImpl -> 206
com.sun.tools.example.debug.expr.ExpressionParser -> 206
com.sun.org.apache.bcel.internal.generic.EmptyVisitor -> 180
com.sun.org.apache.bcel.internal.generic.Visitor -> 180
ちなみに、static メソッドのみを取り出した場合は以下です。
java.util.Arrays static -> 114
java.nio.Bits static -> 114
apple.laf.AquaImageFactory static -> 98
java.lang.Character static -> 80
sun.awt.FontConfiguration static -> 79
com.sun.security.sasl.digest.DigestMD5Base static -> 70
com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary static -> 69
java.net.URI static -> 66
apple.laf.AquaSliderUI static -> 65
com.sun.tools.corba.se.idl.ParseException static -> 63
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 | import java.io.*;
import java.lang.reflect.*;
import java.util.Map.Entry;
import java.util.jar.*;
import java.util.*;
public class Sample {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Map<String, Integer> classMap = new HashMap<String, Integer>();
for (String jarName : System.getProperty("sun.boot.class.path").split(System.getProperty("path.separator"))) {
File jar = new File(jarName);
if (jar.isFile()) {
JarFile jf = new JarFile(jar);
for (Enumeration<JarEntry> i = jf.entries(); i.hasMoreElements();) {
String entry = i.nextElement().getName();
if (entry.endsWith(".class")) {
String className = entry.substring(0, entry.length() - 6).replaceAll("/", ".");
Class<?> cc = Class.forName(className, false, null);
int staticCount = 0, memberCount = 0;
for (Method m : cc.getDeclaredMethods()) {
if ((m.getModifiers() & Modifier.STATIC) != 0)
staticCount++;
else
memberCount++;
}
classMap.put(className, memberCount);
classMap.put(className + " static", staticCount);
}
}
}
}
Map.Entry<String, Integer>[] a = classMap.entrySet().toArray(new Map.Entry[0]);
Arrays.sort(a, new Comparator<Map.Entry<String, Integer>> () {
public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
return -o1.getValue().compareTo(o2.getValue());
}
});
for (int i = 0; i < 10; i++) {
System.out.printf("%s -> %d%n", a[i].getKey(), a[i].getValue());
}
}
}
|
Fan 1.0.44で。 Podはnamespaceのようなもの、Typeはクラスのようなものです。 継承したメソッドを判別する綺麗な方法はないようで、いったん文字列に変換して比較する、という回りくどい事をやってます。 出力行数は十分小さいと仮定してエラーチェック手抜きしてます。 実行結果 % fan Doukaku270.fan web::WebOutStream, 95 compiler::Parser, 84 compiler::CodeAsm, 75 compiler::CheckErrors, 74 sys::Buf, 71 sys::List, 65 sys::Str, 65 compiler::CType, 62 testSys::DateTimeTest, 54 testSys::StrTest, 52 testSys::UriTest, 52 %
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 | class Doukaku270
{
static const Int numClassesToDisplay := 10
Void main() {
Int:Type[] counts := [:] // 連想配列: メソッド数 -> クラスのリスト
// countsを埋める
Pod.list.each |Pod pod| {
pod.types.each |Type type| {
numMethods := type.methods.findAll {
// 継承したものでなく、このクラスで実装されたものを選ぶ
it.toStr.startsWith("${type.toStr}.")
}.size
counts[numMethods] = counts.get(numMethods, [,]).add(type)
}
}
numPrints := 0 // 出力済みの行数
keys := counts.keys.sortr
while (numPrints < numClassesToDisplay) {
numMethods := keys.removeAt(0)
counts[numMethods].each |Type type| {
echo("${type.toStr}, $numMethods")
}
numPrints += counts[numMethods].size
}
}
}
|
total: 135
String: 369
Array: 355
File: 349
IO: 340
Hash: 334
Class: 332
Module: 331
Fixnum: 329
Bignum: 327
File::Stat: 322
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 | list = []
ObjectSpace.each_object(Class) do |klass|
info = {
:name => klass.name,
:methods => {
:instance_methods => {
:public => klass.public_instance_methods,
:protected => klass.protected_instance_methods,
:private => klass.private_instance_methods
},
:class_methods => {
:public => klass.class.public_instance_methods,
:protected => klass.class.protected_instance_methods,
:private => klass.class.private_instance_methods
}
}
}
info.instance_eval do |obj|
def name
self[:name]
end
def method_count
[:instance_methods, :class_methods].inject(0) do |c, t|
c + [:public, :protected, :private].inject(0) do |r, s|
r + self[:methods][t][s].size
end
end
end
end
list << info
end
puts "total:\t#{list.size}"
list.sort { |a,b| b.method_count <=> a.method_count }[0..9].each do |e|
puts "#{e.name}:\t#{e.method_count}"
end
|
total: 3173
scala.swing.Key: 206
scala.collection.jcl.Buffer$Projection: 166
scala.collection.jcl.ArrayList: 158
scala.collection.jcl.LinkedList: 158
scala.collection.jcl.Buffer$$anon$2: 155
scala.collection.jcl.SortedMap$$anon$1: 153
scala.collection.jcl.TreeMap: 153
scala.collection.jcl.SortedMap$$anon$2: 151
scala.collection.jcl.Buffer$Range: 150
scala.collection.jcl.TreeSet: 146
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import scala.collection.jcl.Conversions
import java.io.File
import java.util.Collections
import java.util.jar.{JarEntry,JarFile}
object MethodCount {
def getClassInformations(l:List[String]):List[Pair[String,Int]] = {
def getInfo(n:String):Pair[String,Int] =
try { (n, Class.forName(n).getDeclaredMethods.size) } catch { case _ => (n, -1) }
def isClass(n:String):Boolean = n.endsWith(".class") && !n.matches("\\$\\$anonfun\\$")
def getClassName(n:String):String = n.substring(0, n.length - 6).replace('/', '.')
def getJarEntries(f:File):List[JarEntry] =
Conversions.convertList(Collections.list((new JarFile(f)).entries)).toList
def getFiles(l:List[String]):List[File] =
l.map(new File(System.getProperty("scala.home"), _)).filter(_.exists)
getFiles(l).map(getJarEntries).flatten(identity(_)).map(_.getName).filter(isClass).map(getClassName).map(getInfo)
}
def main(args:Array[String]):Unit = {
val l:List[Pair[String,Int]] = getClassInformations(List("lib/scala-library.jar", "lib/scala-swing.jar"))
Console.printf("total:\t%d\n", l.size)
l.sort(_._2 > _._2).take(10).foreach((i) => Console.printf("%s:\t%d\n", i._1, i._2))
}
}
|
ghc 限定.Preludeからエクスポートされているclassは15個しかないので全部列挙 (10個に限定するなら,コード中のコメントアウトされている部分をuncommentする) 括弧内がメソッドの数
実行例: *Main> :main Floating (18) RealFloat (14) Enum (8) Ord (7) Num (7) Integral (7) RealFrac (5) Read (5) Monad (4) Show (3) Fractional (3) Eq (2) Bounded (2) Real (1) Functor (1) ... number of classes : 15
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 | import Data.List
import Data.Ord
import System.Process
data ClassInfo = CI { className :: String, numberOfMethods :: Int }
main = do { res <- readProcess "ghc" ["-e",":browse Prelude"] []
; let cis = classInfos [] $ lines res
; let n = length cis
; putStr $ unlines {- $ take 10 -}
$ map showClassInfo $ sortBy (flip (comparing numberOfMethods)) cis
; putStr $ unlines ["...","number of classes : "++show n]
}
showClassInfo :: ClassInfo -> String
showClassInfo (CI name n) = name ++ " (" ++ show n ++ ")"
classInfos :: [ClassInfo] -> [String] -> [ClassInfo]
classInfos a [] = a
classInfos a (l:ls)
| head lw /= "class" = classInfos a ls
| otherwise = classInfos (ci:a) ls''
where
lw = words l
ci = CI name (if null ls' then 1 else length ls')
(ls',ls'') = break (not . (" " `isPrefixOf`)) ls
name = case break ("=>"==) lw of
(_,[]) -> head $ tail lw
(_,lw') -> head $ tail lw'
|
すみません。プレビューせずに、形式をまちがえてupしたので実行例がこわれてしまいました。orz 実行例だけupします *Main> :main Floating (18) RealFloat (14) Enum (8) Ord (7) Num (7) Integral (7) RealFrac (5) Read (5) Monad (4) Show (3) Fractional (3) Eq (2) Bounded (2) Real (1) Functor (1) ... number of classes : 15
Squirrel3.0で。 「継承したメソッド数は含まずに」が出来なかったのでカッとなって横に伸ばした。 反省はしていない。 結果: roottable : 56 blob : 13 file : 10 stream : 9 regexp : 5 ええ、別に継承考慮しなくても結果変わらないんです。 あまりにさみしいので、グローバル関数のようなものをroottableとしてカウントしています。 自分自身が含まれてしまわないようにlocal tab = のような書き方になっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | local tab =
{
function count_function(cla)
{
local ret = 0;
foreach(k,v in cla) if (type(v) == "function") ret++;
return ret;
}
function main()
{
local result = [{ key="roottable", val=count_function(getroottable()) }];
foreach(k,v in getroottable()) if (type(v)=="class") result.append({ key=k, val=count_function(v) });
result.sort(@(a, b) b.val-a.val);
for(local i=0; i<10 && i<result.len(); i++) print(format("%-10s : %3d\n", result[i].key, result[i].val));
}
}
tab.main();
|
>ええ、別に継承考慮しなくても結果変わらないんです。 と思いましたが、fileとblobはstreamを継承してるっぽいですorz
結果
Only regular methods: unicode(39), str(37), set(16), dict(15), file(15), list(9), frozenset(7), complex(1), enumerate(1), reversed(1)
Including special methods: unicode(66), str(64), bool(53), int(53), long(53), set(49), float(46), complex(45), list(41), dict(39)
「標準ライブラリ」は数え切れないほどあって、サードパーティ製との境目が不明瞭になるので、「組み込み」を意味する__builtins__モジュールに限って調査しました。
また、Pythonでは、__XXX__形式の特殊メソッドを実装してオブジェクトの暗黙的な振る舞いを定義するので、それらを含まない場合と含む場合で分けて調査しました。
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 | def bi_of(name):
return getattr(__builtins__, name)
def special_name(a):
return a[0:2] == "__" and a[-2:] == "__"
def bi_methods_of(name):
o = bi_of(name)
return filter(
lambda a: not special_name(a) and callable(getattr(o, a)),
dir(o))
def bi_all_methods_of(name):
o = bi_of(name)
return filter(
lambda a: callable(getattr(o, a)),
dir(o))
def class_method_ranking(counter_func, limit):
return map(
lambda name: "%s(%d)" % (name, len(counter_func(name))),
sorted(
filter(
lambda name: type(bi_of(name)) == type,
dir(__builtins__)),
lambda a,b: cmp(
len(counter_func(a)),
len(counter_func(b))
) * -1
)[0:limit]
)
print "Only regular methods: %s" % ", ".join(
class_method_ranking(bi_methods_of, 10))
print "Including special methods: %s" % ", ".join(
class_method_ranking(bi_all_methods_of, 10))
|
GDKの追加メソッドで調べてみました。具体的には、org.codehaus.groovy.runtime.*パッケージのDefaultGroovyMethods, DefaultGroovyStaticMethods, SwingGroovyMethodの3つのクラスで定義されているメソッドからです。
結果はこんな感じ。
1 : class java.lang.String=72
2 : class java.io.File=63
3 : class java.lang.Object=57
4 : interface java.util.Collection=44
5 : class java.lang.Number=33
6 : class [Ljava.lang.Object;=31
7 : interface java.util.Map=25
8 : interface java.util.List=25
9 : class java.io.InputStream=23
10 : class java.lang.Character=22
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import org.codehaus.groovy.runtime.*
counter=[:]
[DefaultGroovyMethods,
DefaultGroovyStaticMethods,
SwingGroovyMethods].each {
it.methods.each {
if (it.parameterTypes.size() != 0) {
cls = it.parameterTypes[0]
counter[cls]==null? counter[cls]=1 : counter[cls]++
}
}
}
counter.entrySet().sort { -it.value }[0..9].eachWithIndex { it, idx ->
println "${idx+1} : $it"
}
|
Hello! :) is it work? <a href=http://test.com>test</a>
see: Hello





sumim
#9197()
Rating-1/5=-0.20
言語処理系に組み込みの全クラスについて、それぞれに定義されているメソッド数が多い順に上位10番目までのクラス名とメソッド数を出力するコードを書いてください。全クラス数も示してください。
なお、「組み込み」「クラス」「メソッド」などについては、必要であれば、その言語にふさわしい対象や機能に適宜読み替えてください。(たとえば、組み込み→標準添付、クラス→型・モジュール・パッケージ…、メソッド→関数・プロシージャ…といった具合に)
2 replies [ reply ]