crosscounter 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d23bb8b769b17271893ecad937b0e452c9915f6d
4
+ data.tar.gz: 9430375da9fe90ffba3c47e9d0112f58ceb13e3d
5
+ SHA512:
6
+ metadata.gz: d77812e65a457eed6efe99f1804c514e59cc4ade31a7b73d901e7d3b7050babca2a76826617fba7d4ae0e5582bf8dd12e060420c9b0bf3370e43b002be8e203b
7
+ data.tar.gz: d665c48e4584ec3bb2a2e44aa6b493f770d5b24f924483038c8ac2eddd6f81ee59d63b2e381d58e004bbdbc3ab1c13a1bcb3a742fa085d07dfb9dc1101189752
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format progress
3
+ -r spec_helper
data/.travis.yml CHANGED
@@ -1,3 +1,5 @@
1
1
  language: ruby
2
+ cache: bundler
2
3
  rvm:
3
4
  - 1.9.3
5
+ - 2.1.0
data/NOTES.txt CHANGED
@@ -1,70 +1,114 @@
1
- ---
1
+ # Profile as of dafc032
2
2
 
3
- n = 1_000_000
4
- Benchmark.bm do |x|
5
- x.report { n.times { friendly_words.include?('mandarin') } }
6
- x.report { n.times { friendly_string =~ /mandarin/ } }
7
- x.report { n.times { friendly_string['mandarin'] } }
8
- x.report { n.times { friendly_string.index('mandarin') } }
9
- end
3
+ Total: 145.487024
4
+ Sort by: self_time
10
5
 
11
- Matching against values as a string is ~7x faster
12
-
13
- user system total real
14
- 5.630000 0.000000 5.630000 ( 5.625129)
15
- 0.790000 0.000000 0.790000 ( 0.788589)
16
- 1.190000 0.000000 1.190000 ( 1.192151)
17
- 1.190000 0.000000 1.190000 ( 1.187852)
6
+ %self total self wait child calls name
7
+ 45.73 107.438 66.532 0.000 40.906 14675390 Hash#each
8
+ 14.30 128.248 20.812 0.000 107.437 14675388 Enumerable#all?
9
+ 12.15 30.163 17.675 0.000 12.488 8346096 Array#include?
10
+ 11.59 145.109 16.861 0.000 128.248 27482 Array#count
11
+ 8.58 12.488 12.488 0.000 0.000 21735448 String#==
12
+ 6.53 9.502 9.502 0.000 0.000 15295038 Kernel#kind_of?
13
+ 0.85 1.241 1.241 0.000 0.000 619650 String#sub
14
+ 0.14 143.935 0.202 0.000 143.733 836 Array#each
15
+ 0.03 145.158 0.049 0.000 145.109 27482 Crosscounter::Compute#compute
16
+ 0.03 0.036 0.036 0.000 0.000 54975 Array#last
17
+ 0.02 0.036 0.036 0.000 0.000 55054 Array#first
18
+ 0.01 0.037 0.020 0.000 0.017 615 Array#hash
19
+ 0.01 0.017 0.017 0.000 0.000 28187 String#hash
20
+ 0.00 145.487 0.004 0.000 145.483 13 *Array#map
21
+ 0.00 0.003 0.003 0.000 0.000 4806 Hash#delete
22
+ 0.00 0.003 0.003 0.000 0.000 5198 String#to_s
23
+ 0.00 0.040 0.002 0.000 0.037 304 Hash#hash
24
+ 0.00 0.043 0.002 0.000 0.041 303 Crosscounter::Util#tuplize
25
+ 0.00 0.017 0.001 0.000 0.015 534 Crosscounter::Util#stringify_keys
26
+ 0.00 143.921 0.001 0.000 143.920 302 Enumerable#inject
27
+ 0.00 0.000 0.000 0.000 0.000 534 Hash#keys
28
+ 0.00 145.487 0.000 0.000 145.487 1 Global#[No method]
29
+ 0.00 145.487 0.000 0.000 145.487 1 Crosscounter::Compute#compute_all
30
+ 0.00 0.001 0.000 0.000 0.001 2 Enumerable#flat_map
31
+ 0.00 0.017 0.000 0.000 0.017 1 Crosscounter::Util#stringify_all
18
32
 
19
- ---
33
+ # Profile as of 86b6735f
20
34
 
21
- # 1 Total: 194.028314
35
+ Total: 95.443315
36
+ Sort by: self_time
22
37
 
23
38
  %self total self wait child calls name
24
- 37.23 164.362 72.237 0.000 92.125 10681477 *Hash#each
25
- 11.02 21.382 21.380 0.000 0.001 10972331 <Module::Crosscounter::Compute>#regexify
26
- 10.90 21.147 21.146 0.000 0.000 10972547 String#sub
27
- 7.86 177.838 15.241 0.000 162.596 10676448 Enumerable#all?
28
- 7.02 13.617 13.617 0.000 0.000 10974955 String#=~
29
- 6.78 190.996 13.158 0.000 177.838 13566 Array#count
30
- 4.73 9.179 9.179 0.000 0.000 10972581 Hash#fetch
31
- 4.66 9.047 9.047 0.000 0.000 11043313 Symbol#to_s
32
- 4.47 8.676 8.676 0.000 0.000 10972786 String#to_sym
33
- 3.02 5.866 5.866 0.000 0.000 9305498 String#to_s
34
- 0.81 1.577 1.577 0.000 0.000 1706407 Fixnum#to_s
35
- 0.06 188.146 0.118 0.000 188.028 8381 *Array#each
36
- 0.05 192.566 0.105 0.000 192.460 4174 *Array#map
37
- 0.04 0.079 0.079 0.000 0.000 8026 String#gsub
39
+ 24.92 34.030 23.780 0.000 10.250 15295038 Set#include?
40
+ 18.47 78.989 17.624 0.000 61.365 14675388 Enumerable#all?
41
+ 17.04 95.254 16.265 0.000 78.989 27482 Array#count
42
+ 10.74 10.250 10.250 0.000 0.000 15295038 Hash#include?
43
+ 0.37 94.999 0.351 0.000 94.648 14676224 *Array#each
44
+ 0.05 95.299 0.045 0.000 95.254 27482 Crosscounter::Compute#compute
45
+ 0.02 0.054 0.017 0.000 0.037 837 Hash#each
46
+ 0.01 0.014 0.014 0.000 0.000 6884 Set#add
47
+ 0.00 0.004 0.004 0.000 0.000 5419 Kernel#kind_of?
48
+ 0.00 0.034 0.003 0.000 0.031 534 Set#initialize
49
+ 0.00 0.029 0.002 0.000 0.027 534 Set#merge
50
+ 0.00 95.443 0.002 0.000 95.441 2751 *Array#map
51
+ 0.00 0.056 0.002 0.000 0.055 837 Crosscounter::Util#stringify
52
+ 0.00 0.026 0.002 0.000 0.025 534 Set#do_with_enum
53
+ 0.00 0.055 0.001 0.000 0.054 837 Enumerable#flat_map
54
+ 0.00 0.061 0.001 0.000 0.060 534 Crosscounter::Util#setify
55
+ 0.00 0.035 0.001 0.000 0.034 1068 *Class#new
56
+ 0.00 0.024 0.001 0.000 0.023 534 Enumerable#each_entry
57
+ 0.00 94.319 0.001 0.000 94.318 302 Enumerable#inject
58
+ 0.00 0.001 0.001 0.000 0.000 534 Hash#initialize
59
+ 0.00 0.000 0.000 0.000 0.000 534 Kernel#respond_to?
60
+ 0.00 0.000 0.000 0.000 0.000 534 Kernel#nil?
61
+ 0.00 0.000 0.000 0.000 0.000 534 Kernel#instance_of?
62
+ 0.00 0.000 0.000 0.000 0.000 534 Kernel#class
63
+ 0.00 95.443 0.000 0.000 95.443 1 Global#[No method]
64
+ 0.00 95.443 0.000 0.000 95.443 1 Crosscounter::Compute#compute_all
65
+
66
+ # Profile as of 746633d
38
67
 
39
- # 2 Total: 112.476687 (1.73x Faster)
68
+ Total: 50.415018
69
+ Sort by: self_time
40
70
 
41
71
  %self total self wait child calls name
42
- 39.07 84.951 43.949 0.000 41.002 10681477 *Hash#each
43
- 17.29 19.451 19.450 0.000 0.001 10972331 <Module::Crosscounter::Compute>#regexify
44
- 12.52 97.285 14.085 0.000 83.200 10676448 Enumerable#all?
45
- 11.02 12.400 12.400 0.000 0.000 10974955 String#=~
46
- 10.87 109.508 12.224 0.000 97.285 13566 Array#count
47
- 4.78 5.379 5.379 0.000 0.000 9305498 String#to_s
48
- 1.33 1.494 1.494 0.000 0.000 1706407 Fixnum#to_s
49
- 0.53 0.596 0.596 0.000 0.000 305605 String#sub
50
- 0.09 110.965 0.104 0.000 110.860 4174 *Array#map
51
- 0.09 108.632 0.096 0.000 108.536 9168 *Array#each
52
- 0.08 0.139 0.089 0.000 0.050 8605 ActiveSupport::Callbacks::ClassMethods#__callback_runner_name
53
- 0.06 0.088 0.068 0.000 0.021 4722 <Class::ActiveSupport::TimeZone>#seconds_to_utc_offset
54
- 0.04 0.050 0.050 0.000 0.000 64463 Symbol#to_s
55
- 0.04 0.108 0.049 0.000 0.059 7875 ActiveRecord::AttributeMethods::Read::ClassMethods#type_cast_attribute
56
- 0.04 0.056 0.047 0.000 0.009 4210 <Class::Hash>#[]
57
- 0.04 0.326 0.046 0.000 0.281 11530 ActiveRecord::AttributeMethods#respond_to?
58
- 0.04 0.684 0.044 0.000 0.641 4191 ActiveRecord::Base#init_with
59
- 0.04 0.041 0.041 0.000 0.000 8026 String#gsub
72
+ 47.33 33.178 23.862 0.000 9.317 15295038 Set#include?
73
+ 33.90 50.270 17.091 0.000 33.178 27482 Array#count
74
+ 18.48 9.317 9.317 0.000 0.000 15295038 Hash#include?
75
+ 0.10 49.839 0.050 0.000 49.789 836 Array#each
76
+ 0.09 50.315 0.045 0.000 50.270 27482 Crosscounter::Compute#compute
77
+ 0.03 0.013 0.013 0.000 0.000 6884 Set#add
78
+ 0.03 0.022 0.013 0.000 0.009 536 Hash#each
79
+ 0.01 0.003 0.003 0.000 0.000 4817 Kernel#kind_of?
80
+ 0.00 0.031 0.002 0.000 0.029 534 Set#initialize
81
+ 0.00 0.027 0.002 0.000 0.025 534 Set#merge
82
+ 0.00 50.415 0.002 0.000 50.413 2149 *Array#map
83
+ 0.00 0.024 0.001 0.000 0.023 534 Set#do_with_enum
84
+ 0.00 0.056 0.001 0.000 0.055 534 Crosscounter::Util#setify
85
+ 0.00 0.024 0.001 0.000 0.023 536 Crosscounter::Util#stringify
86
+ 0.00 0.032 0.001 0.000 0.031 1068 *Class#new
87
+ 0.00 0.023 0.001 0.000 0.022 536 Enumerable#flat_map
88
+ 0.00 49.818 0.001 0.000 49.817 302 Enumerable#inject
89
+ 0.00 0.022 0.001 0.000 0.022 534 Enumerable#each_entry
90
+ 0.00 0.001 0.001 0.000 0.000 534 Hash#initialize
91
+ 0.00 0.000 0.000 0.000 0.000 534 Kernel#respond_to?
92
+ 0.00 0.000 0.000 0.000 0.000 534 Kernel#instance_of?
93
+ 0.00 0.000 0.000 0.000 0.000 534 Kernel#class
94
+ 0.00 0.000 0.000 0.000 0.000 534 Kernel#nil?
95
+ 0.00 50.415 0.000 0.000 50.415 1 Global#[No method]
96
+ 0.00 50.415 0.000 0.000 50.415 1 Crosscounter::Compute#compute_all
60
97
 
61
- # Total: 92.512639 (1.21x Faster)
98
+ Total: 26.442810
99
+ Sort by: self_time
62
100
 
63
101
  %self total self wait child calls name
64
- 50.37 65.501 46.595 0.000 18.906 10681477 *Hash#each
65
- 14.75 77.401 13.648 0.000 63.753 10676448 Enumerable#all?
66
- 13.03 89.452 12.051 0.000 77.401 13566 Array#count
67
- 7.61 7.039 7.039 0.000 0.000 10894304 Kernel#kind_of?
68
- 2.15 3.004 1.986 0.000 1.018 1670405 String#==
69
- 2.12 1.959 1.958 0.000 0.000 1040575 Array#join
70
- 2.08 4.924 1.920 0.000 3.004 1670214 Fixnum#==
102
+ 64.06 26.310 16.939 0.000 9.371 27482 Array#count
103
+ 35.44 9.371 9.371 0.000 0.000 15295038 Hash#member?
104
+ 0.22 26.123 0.058 0.000 26.064 836 Array#each
105
+ 0.17 26.356 0.046 0.000 26.310 27482 Crosscounter::Compute#compute
106
+ 0.05 0.022 0.013 0.000 0.009 536 Hash#each
107
+ 0.01 0.003 0.003 0.000 0.000 4817 Kernel#kind_of?
108
+ 0.01 26.443 0.002 0.000 26.441 2149 *Array#map
109
+ 0.01 26.124 0.002 0.000 26.123 836 Enumerable#inject
110
+ 0.00 0.037 0.001 0.000 0.036 534 Crosscounter::Util#hashify
111
+ 0.00 0.024 0.001 0.000 0.023 536 Crosscounter::Util#stringify
112
+ 0.00 0.023 0.001 0.000 0.022 536 Enumerable#flat_map
113
+ 0.00 26.443 0.000 0.000 26.443 1 Global#[No method]
114
+ 0.00 26.443 0.000 0.000 26.443 1 Crosscounter::Compute#compute_all
data/README.md CHANGED
@@ -1,3 +1,6 @@
1
+ [![Code Climate](https://codeclimate.com/github/sorentwo/crosscounter.png)](https://codeclimate.com/github/sorentwo/crosscounter)
2
+ [![Build Status](https://travis-ci.org/sorentwo/crosscounter.png?branch=master)](https://travis-ci.org/sorentwo/crosscounter)
3
+
1
4
  # Crosscounter
2
5
 
3
6
  A set of functional tools for generating cross tabulations.
@@ -6,11 +9,50 @@ A set of functional tools for generating cross tabulations.
6
9
 
7
10
  Add this line to your application's Gemfile:
8
11
 
9
- gem 'crosscounter', '~> 0.1.0.beta'
12
+ ```ruby
13
+ gem 'crosscounter'
14
+ ```
10
15
 
11
16
  ## Usage
12
17
 
13
- This is in early development. It isn't intended for general use.
18
+ Crosscounter works entirely with standard data structures, i.e. arrays and
19
+ hashes. General usage is to provide an enumerable containing hashes of values,
20
+ followed by a rows hash and a columns hash.
21
+
22
+
23
+ ```ruby
24
+ enumerable = [
25
+ { age: 18, gender: 'male', tags: %w[happy sad] },
26
+ { age: 19, gender: 'female', tags: %w[happy mad] },
27
+ { age: 18, gender: 'male', tags: %w[mad sad] },
28
+ { age: 19, gender: 'male', tags: %w[sad] }
29
+ ]
30
+
31
+ rows = {
32
+ age: [18, 19],
33
+ gender: %w[male female],
34
+ tags: %w[happy sad mad]
35
+ }
36
+
37
+ cols = { tags: %w[happy sad mad] }
38
+
39
+ computer.compute_all(enumerable, rows, cols) #=> [
40
+ [18, 2, 1, 2, 1],
41
+ [19, 2, 1, 1, 1],
42
+ ['male', 3, 1, 3, 1],
43
+ ['female', 1, 1, 0, 1],
44
+ ['happy', 2, 2, 1, 1],
45
+ ['sad', 3, 1, 3, 1],
46
+ ['mad', 2, 1, 1, 2]
47
+ ]
48
+ ```
49
+
50
+ The resulting output is an array of arrays mapping out every row value against
51
+ every column value. In the example above the columns are:
52
+
53
+ | key | all | tags['happy'] | tags['sad'] | tags['mad'] |
54
+ | --- | --- | ------------- | ----------- | ----------- |
55
+ | 18 | 2 | 1 | 2 | 1 |
14
56
 
15
57
  ## Contributing
16
58
 
data/Rakefile CHANGED
@@ -4,4 +4,4 @@ require 'rspec/core/rake_task'
4
4
 
5
5
  RSpec::Core::RakeTask.new :spec
6
6
 
7
- task :default => :spec
7
+ task default: :spec
data/bench/cols.json ADDED
@@ -0,0 +1 @@
1
+ {"answers":["Q4 This is a big step forward.","Q4 This is a little step forward.","Q4 This is a big step back.","Q4 This is a little step back.","Q4 I'm not sure yet!","Q6 Apple is leading.","Q6 Apple is following.","Q9 constantly (many times daily)","Q9 often (daily)","Q9 sometimes (at least once a week)","Q9 infrequently (less than once a week)","Q9 very rarely (or never)"],"tags":["00: stuff","01: wacky","02: data","03: parking","0: parking lot","0: weird","1: air drop","1: battery life","1: control center","1: data detectors","1: fingerprint","1: folders","1: home screen","1: integration","1: lock screen","1: mulltitasking","1: notification center","1: other","1: ringtones","1: settings","1: siri","1: slide to","1: spotlight","2: app store","2: calendar","2: camera","2: clock","2: compass","2: facetime","2: game center","2: mail","2: maps","2: messages","2: music","2: notes","2: other","2: passbook","2: phone","2: photos","2: reminders","2: safari","2: videos","2: weather","3: backgrounds","3: colors","3: icons","3: motion","3: other","3: transparency","3: typography","4: bug/crash/etc","4: functionality","4: other","4: privacy","4: usability","5: aesthetics","5: integration","5: learning/context/automation","5: none","5: options/settings","5: other","5: revert","6: can't update","6: fantastic","6: gratuitious","at: android","at: apple","at: clean","at: color","at: control center","at: flashlight","at: flat","at: home","at: icon","at: multitasking","at: pretty","at: swipe","auto: color"]}
data/bench/compute.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'bundler'
2
+
3
+ Bundler.setup
4
+
5
+ require 'benchmark'
6
+ require 'crosscounter'
7
+ require 'json'
8
+
9
+ rows = JSON.load(IO.read('bench/rows.json'))
10
+ cols = JSON.load(IO.read('bench/cols.json'))
11
+ data = JSON.load(IO.read('bench/data.json'))
12
+
13
+ if ENV['PROFILE']
14
+ require 'ruby-prof'
15
+
16
+ result = RubyProf.profile do
17
+ Crosscounter::Compute.compute_all(data, rows, cols)
18
+ end
19
+
20
+ printer = RubyProf::FlatPrinter.new(result)
21
+ printer.print(STDOUT)
22
+ else
23
+ Benchmark.bmbm do |x|
24
+ x.report('compute_all' ) do
25
+ Crosscounter::Compute.compute_all(data, rows, cols)
26
+ end
27
+ end
28
+ end