hashugar 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .rbx
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ .idea
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ 1.9.3@hashugar --create
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in hashugar.gemspec
4
+ gemspec
5
+
6
+ gem 'rake'
@@ -0,0 +1,48 @@
1
+ Hashugar
2
+ ========
3
+
4
+ Nested OpenStruct alternative optimized for speed especially for many short-lived objects (e.g. results from db).
5
+
6
+
7
+ Usage
8
+ -----
9
+
10
+ `$ gem install hashugar`
11
+
12
+ -----
13
+ ```ruby
14
+ hashugar = {:a => 1, 'b' => {:c => 3}}.to_hashugar
15
+ hashugar.a # => 1
16
+ hashugar.b # => 2
17
+ hashugar.b.c # => 3
18
+ ```
19
+
20
+ How fast is it?
21
+ ---------------
22
+
23
+ Ruby 1.9.3 benchmark
24
+
25
+ OpenStruct create small hash and access once
26
+ 25546.3 (±5.9%) i/s - 128865 in 5.060934s (cycle=2343)
27
+ Hashugar create small hash and access once
28
+ 570523.2 (±6.3%) i/s - 2857400 in 5.031212s (cycle=28574)
29
+
30
+ OpenStruct create big hash and access once
31
+ 780.5 (±8.5%) i/s - 3927 in 5.066012s (cycle=77)
32
+ Hashugar create big hash and access once
33
+ 779118.2 (±4.4%) i/s - 3911640 in 5.031364s (cycle=32597)
34
+
35
+ OpenStruct create small hash and access ten times
36
+ 29389.7 (±10.6%) i/s - 146720 in 5.058931s (cycle=2620)
37
+ Hashugar create small hash and access ten times
38
+ 105626.2 (±3.7%) i/s - 534421 in 5.066869s (cycle=8761)
39
+
40
+ OpenStruct create small hash and access fifty times
41
+ 24329.8 (±4.2%) i/s - 123390 in 5.082089s (cycle=2285)
42
+ Hashugar create small hash and access fifty times
43
+ 22246.2 (±2.9%) i/s - 112008 in 5.039232s (cycle=2154)
44
+
45
+ OpenStruct create small hash and access hundred times
46
+ 20432.0 (±13.4%) i/s - 100912 in 5.011692s (cycle=1904)
47
+ Hashugar create small hash and access hundred times
48
+ 11296.5 (±3.3%) i/s - 56940 in 5.046262s (cycle=1095)
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new('spec')
6
+
7
+ # If you want to make this the default task
8
+ task :default => :spec
9
+
10
+ desc "Benchmark"
11
+ task :bench do
12
+ require 'benchmark/ips'
13
+ require 'ostruct'
14
+ require 'hashugar'
15
+
16
+ SMALL_HASH = {:a => 1, :b => 2}
17
+ BIG_HASH = {}; 100.times {|i| BIG_HASH[i.to_s] = "item#{i}" }
18
+
19
+ Benchmark.ips do |x|
20
+ x.report 'OpenStruct create small hash and access once', 'OpenStruct.new(SMALL_HASH).item5'
21
+ x.report 'Hashugar create small hash and access once', 'Hashugar.new(SMALL_HASH).item5'
22
+
23
+ x.report 'OpenStruct create big hash and access once', 'OpenStruct.new(BIG_HASH).item5'
24
+ x.report 'Hashugar create big hash and access once', 'Hashugar.new(BIG_HASH).item5'
25
+
26
+ x.report 'OpenStruct create small hash and access ten times', 'h = OpenStruct.new(SMALL_HASH); i = 0; while i < 10; h.a; i += 1; end'
27
+ x.report 'Hashugar create small hash and access ten times', 'h = Hashugar.new(SMALL_HASH); i = 0; while i < 10; h.a; i += 1; end'
28
+
29
+ x.report 'OpenStruct create small hash and access fifty times', 'h = OpenStruct.new(SMALL_HASH); i = 0; while i < 50; h.a; i += 1; end'
30
+ x.report 'Hashugar create small hash and access fifty times', 'h = Hashugar.new(SMALL_HASH); i = 0; while i < 50; h.a; i += 1; end'
31
+
32
+ x.report 'OpenStruct create small hash and access hundred times', 'h = OpenStruct.new(SMALL_HASH); i = 0; while i < 100; h.a; i += 1; end'
33
+ x.report 'Hashugar create small hash and access hundred times', 'h = Hashugar.new(SMALL_HASH); i = 0; while i < 100; h.a; i += 1; end'
34
+ end
35
+ end
data/TODO ADDED
@@ -0,0 +1,6 @@
1
+ TODO
2
+ - Basic hash methods each_pair...
3
+
4
+ Ideas
5
+ - HotSpot-like define method - after many calls of method_missing define getter/setter
6
+ - Lazy convert hash
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/hashugar/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Jan Suchal"]
6
+ gem.email = ["johno@jsmf.net"]
7
+ gem.summary = %q{Fast Nested OpenStruct}
8
+ gem.description = %q{Nested OpenStruct optimized for short-lived objects.}
9
+ gem.homepage = "http://github.com/jsuchal/hashugar"
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "hashugar"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Hashugar::VERSION
17
+
18
+ gem.add_development_dependency 'rspec'
19
+ gem.add_development_dependency 'benchmark_suite'
20
+ gem.add_development_dependency 'ffi'
21
+ end
@@ -0,0 +1,55 @@
1
+ require "hashugar/version"
2
+
3
+ class Hashugar
4
+ def initialize(hash)
5
+ @table = hash
6
+ end
7
+
8
+ def method_missing(method, *args, &block)
9
+ method = method.to_s
10
+ if method.chomp!('=')
11
+ self[method] = args.first
12
+ else
13
+ @table[method]
14
+ end
15
+ end
16
+
17
+ def [](key)
18
+ @table[convert_key(key)]
19
+ end
20
+
21
+ def []=(key, value)
22
+ @table[convert_key(key)] = value
23
+ end
24
+
25
+ def to_hashugar
26
+ self
27
+ end
28
+
29
+ private
30
+ def convert_key(key)
31
+ key.is_a?(Symbol) ? key.to_s : key
32
+ end
33
+ end
34
+
35
+ class Hash
36
+ def to_hashugar
37
+ # TODO lazy?
38
+ table = {}
39
+ each_pair do |key, value|
40
+ table[convert_key(key)] = value.to_hashugar
41
+ end
42
+ Hashugar.new(table)
43
+ end
44
+
45
+ private
46
+ def convert_key(key)
47
+ key.is_a?(Symbol) ? key.to_s : key
48
+ end
49
+ end
50
+
51
+ class Object
52
+ def to_hashugar
53
+ self
54
+ end
55
+ end
@@ -0,0 +1,3 @@
1
+ class Hashugar
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hashugar do
4
+ context 'when accessing simple hash' do
5
+ it 'should be make accessible string and symbol keys' do
6
+ hashugar = {:a => 1, 'b' => 2}.to_hashugar
7
+ hashugar.a.should == 1
8
+ hashugar.b.should == 2
9
+ end
10
+
11
+ it 'should be readable through nice methods' do
12
+ hashugar = {:a => 1, :b => 2}.to_hashugar
13
+ hashugar.a.should == 1
14
+ hashugar.b.should == 2
15
+ end
16
+
17
+ it 'should be writable through nice methods' do
18
+ hashugar = {:a => 1}.to_hashugar
19
+ hashugar.a = 2
20
+ hashugar.b = 3
21
+ hashugar.a.should == 2
22
+ hashugar.b.should == 3
23
+ end
24
+
25
+ it 'should be readable through old methods' do
26
+ hashugar = {:a => 1}.to_hashugar
27
+ hashugar[:a].should == 1
28
+ hashugar['a'].should == 1
29
+ end
30
+
31
+ it 'should be writable through old methods' do
32
+ hashugar = {:a => 1}.to_hashugar
33
+ hashugar['a'] = 2
34
+ hashugar.a.should == 2
35
+ hashugar[:a] = 3
36
+ hashugar.a.should == 3
37
+ end
38
+ end
39
+
40
+ context 'when accessing nested hash' do
41
+ it 'should be writable through nice methods' do
42
+ hashugar = {:a => {:b => 1}}.to_hashugar
43
+ hashugar.a.b.should == 1
44
+ end
45
+
46
+ it 'should be writable through nice methods' do
47
+ hashugar = {:a =>{}}.to_hashugar
48
+ hashugar.a.b = 1
49
+ hashugar.a.b.should == 1
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'hashugar'
5
+
6
+ RSpec.configure do |config|
7
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hashugar
3
+ version: !ruby/object:Gem::Version
4
+ hash: 856480538658449761
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Jan Suchal
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-12-07 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 2002549777813010636
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: benchmark_suite
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 2002549777813010636
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: ffi
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 2002549777813010636
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :development
62
+ version_requirements: *id003
63
+ description: Nested OpenStruct optimized for short-lived objects.
64
+ email:
65
+ - johno@jsmf.net
66
+ executables: []
67
+
68
+ extensions: []
69
+
70
+ extra_rdoc_files: []
71
+
72
+ files:
73
+ - .gitignore
74
+ - .rvmrc
75
+ - Gemfile
76
+ - README.md
77
+ - Rakefile
78
+ - TODO
79
+ - hashugar.gemspec
80
+ - lib/hashugar.rb
81
+ - lib/hashugar/version.rb
82
+ - spec/hashugar_spec.rb
83
+ - spec/spec_helper.rb
84
+ has_rdoc: true
85
+ homepage: http://github.com/jsuchal/hashugar
86
+ licenses: []
87
+
88
+ post_install_message:
89
+ rdoc_options: []
90
+
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ hash: 2002549777813010636
99
+ segments:
100
+ - 0
101
+ version: "0"
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ hash: 2002549777813010636
108
+ segments:
109
+ - 0
110
+ version: "0"
111
+ requirements: []
112
+
113
+ rubyforge_project:
114
+ rubygems_version: 1.5.2
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: Fast Nested OpenStruct
118
+ test_files:
119
+ - spec/hashugar_spec.rb
120
+ - spec/spec_helper.rb