- お知らせ -
  • 当wikiのプログラムコードの表示を直してみました(ついでに長い行があると全体が下にぶっ飛ぶのも修正)。不具合があればBBSまでご連絡下さい。

Ruby/C言語のstruct(構造体)を使いたい

はじめに Edit

Struct vs OpenStruct vs Hash(string, symbol)
どれが速いのですか?という話です。

検証コード Edit

適当ベンチマークを書きなぐってみました。
DRYのためにメソッド呼び出しコスト、ブロック呼び出しコストとかあるけどある程度はキニシナイ!!

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
$KCODE = 'u'

require 'benchmark'
require 'ostruct'

Human = Struct.new(:name, :age)

def modify_struct(struct)
  struct.name = "mage".to_s
  struct.age = 1234
  value = struct.name
  value = struct.age
end

def modify_hash_by_symbol(hash)
  hash[:name] = "mage".to_s
  hash[:age] = 1234
  value = hash[:name]
  value = hash[:age]
end

def modify_hash(hash)
  hash["name"] = "mage".to_s
  hash["age"] = 1234
  value = hash["name"]
  value = hash["age"]
end

def do_benchmark(name, benchmark, loop_num, arg = nil)
  benchmark.report(name) do
    loop_num.times { yield arg }
  end
end

n = 20000
Benchmark.bmbm do |x|
  do_benchmark("Struct(new and modify)", x, n) do
    modify_struct(Human.new)
  end
  
  do_benchmark("OpenStruct(new and modify)", x, n) do
    modify_struct(OpenStruct.new)
  end
  
  do_benchmark("Hash with symbol key(new and modify)", x, n) do
    modify_hash_by_symbol(Hash.new)
  end
  
  do_benchmark("Hash with string key(new and modify)", x, n) do
    modify_hash(Hash.new)
  end

  do_benchmark("Struct(modify only)", x, n, Human.new) do |neko|
    modify_struct(neko)
  end
  
  do_benchmark("OpenStruct(modify only)", x, n, OpenStruct.new) do |neko|
    modify_struct(neko)
  end
  
  do_benchmark("Hash with symbol key(modify only)", x, n, Hash.new) do |neko|
    modify_hash_by_symbol(neko)
  end
  
  do_benchmark("Hash with string key(modify only)", x, n, Hash.new) do |neko|
    modify_hash(neko)
  end
end

puts "\ndone!!"

結果 Edit

環境は、
CPU:Intel QuadCore Q6600(2.4GHz), Memory:2G, OS:Windows Vista SP1
CPU:Pentium D 2.8GHz, Memory:2G, OS:Windows XP SP3
ruby 1.8.7 (2008-06-20 patchlevel 22) [i386-mswin32]

Rehearsal ------------------------------------------------------------------------
Struct(new and modify)                 0.203000   0.000000   0.203000 (  0.218000)
OpenStruct(new and modify)             6.140000   0.203000   6.343000 (  6.407000)
Hash with symbol key(new and modify)   0.250000   0.000000   0.250000 (  0.250000)
Hash with string key(new and modify)   0.266000   0.000000   0.266000 (  0.265000)
Struct(modify only)                    0.125000   0.000000   0.125000 (  0.125000)
OpenStruct(modify only)                0.391000   0.000000   0.391000 (  0.391000)
Hash with symbol key(modify only)      0.093000   0.000000   0.093000 (  0.094000)
Hash with string key(modify only)      0.157000   0.000000   0.157000 (  0.156000)
--------------------------------------------------------------- total: 7.828000sec

                                           user     system      total        real
Struct(new and modify)                 0.218000   0.000000   0.218000 (  0.219000)
OpenStruct(new and modify)             6.375000   0.063000   6.438000 (  6.625000)
Hash with symbol key(new and modify)   0.203000   0.000000   0.203000 (  0.204000)
Hash with string key(new and modify)   0.266000   0.000000   0.266000 (  0.297000)
Struct(modify only)                    0.094000   0.000000   0.094000 (  0.093000)
OpenStruct(modify only)                0.343000   0.000000   0.343000 (  0.359000)
Hash with symbol key(modify only)      0.094000   0.000000   0.094000 (  0.094000)
Hash with string key(modify only)      0.156000   0.000000   0.156000 (  0.156000)

done!!

結論 Edit

Hash(symbol) > Struct > Hash(string) >>>(超えられない壁)>>> OpenStruct

OpenStructは少なくとも、HashやStructの数倍は遅い!
StructよりHashが少し速い。
Hashはstringよりもsymbolをキーにした圧倒的に速い。
Hashかstructかはクリティカルな場面でないならどちらでよいくらいということに。


No comment. Comments/Ruby/C言語のstruct(構造体)を使いたい/ベンチマーク?

Name:

Front page   Edit Freeze Diff Backup Upload Copy Rename Reload   New Pages Search Recent changes   Help   RSS of recent changes
Last-modified: 2008-11-20 Thu 13:34:42 JST (4036d)