graph-function 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +14 -7
- data/examples/comparing.html +18 -18
- data/examples/comparing_canvas.rb +17 -16
- data/lib/graph/function/comparison.rb +1 -1
- data/lib/graph/function/ints_comparison.rb +1 -1
- data/lib/graph/function/only.rb +1 -1
- data/lib/graph/function/version.rb +1 -1
- data/lib/graph/function.rb +2 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37ae0974e3de2c259a00c03fc0e56aa763f4f228
|
4
|
+
data.tar.gz: 37c8a47098d1ff10dff34e64bd975fbdccbd4628
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9550e10b5441a39289e5a0e07be6cee2a4267d341836cedb6fed37b6acb477e28f23c07775cdd4d63cb6ee2c92ce1c0b71811fdc2aa19c0352fdae266d9a11e4
|
7
|
+
data.tar.gz: e08f0b2f4c35cd9d235e27bb5312f16bc7c8c676f3c037e336a26f4e023283ca32b047a44078a0d826173268d3e6443fa89048daebb72e9416db6b920020301c
|
data/README.md
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
# Graph::Function
|
2
2
|
|
3
|
-
|
3
|
+
This gem's goal is to make it easy to compare the [asymptotic performance](https://en.wikipedia.org/wiki/Asymptotic_analysis) of two or more functions via graphing.
|
4
|
+
|
5
|
+
When I work on katas and exercises I found I often wanted to compare my implementations. After doing so a half dozen times I noticed some patterns, and figured it'd be valuable to capture those into an easier API to work with. While working on a kata I like the immediacy of replotting back on x11, but because of gnuplot's structure it is just as easy to get images or html canvas graphs.
|
4
6
|
|
5
7
|
## Disclaimer
|
6
8
|
|
7
|
-
Because of the current implementation details: Ruby methods which operate on `self` **will not work**, and there is a negligible constant slow down on all functions tested because of use of `send(:func)`. The latter won't corrupt comparisons, but means you don't want to use this to benchmark functions individually except through `Graph::Function::Only`.
|
9
|
+
Because of the current implementation details: Ruby methods which operate on `self` **will not work**, and there is a negligible constant slow down on all functions tested by `Comparison` because of the use of `send(:func)`. The latter won't corrupt comparisons, but means you don't want to use this gem to benchmark functions individually **except** through `Graph::Function::Only`.
|
8
10
|
|
9
11
|
## Installation
|
10
12
|
|
@@ -47,10 +49,11 @@ If you don't want to output to x11, just set `config.terminal` to a different op
|
|
47
49
|
Graph::Function.configure do |config|
|
48
50
|
config.terminal = 'gif'
|
49
51
|
config.output = File.expand_path('../your_graph_name.gif', __FILE__)
|
52
|
+
config.step = (0..10_000).step(1000).to_a # default value
|
50
53
|
end
|
51
54
|
```
|
52
55
|
|
53
|
-
|
56
|
+
In configuration, you can also control the "step" size of `x` in the plot. Its default value is `(0..10_000).step(1000).to_a` (`[0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000]`) but you can make it as fine or rough grained as you need up to any size.
|
54
57
|
|
55
58
|
The simplest usage (suitable for a large class of exercises, in my experience) is if you're comparing two functions that take a single argument of `Array[Int]` type:
|
56
59
|
|
@@ -62,21 +65,25 @@ Graph::Function::IntsComparison.of(c.method(:function_name_one), c.method(:funct
|
|
62
65
|
|
63
66
|
![comparison](spec/graph/two_func.gif)
|
64
67
|
|
65
|
-
|
68
|
+
For more complex use cases, you'll be creating a `Graph::Function::Comparison` (or `Graph::Function::Only` if you want to graph a single function) with some generator of data, and executing `#of` with `Method` objects that operate on the same parameter types<sup id="a1">[1](#f1)</sup>. (Note because `IntsComparison` *does not need a generator*, `.of` is a class method instead.)
|
69
|
+
|
70
|
+
To generate values of the type needed by your function, use the provided dependency [Rantly](https://github.com/hayeah/rantly). There's great documentation on generating many different kinds of data in their documentation, but here's an example of comparing two functions that take `Hash{String => Integer}`:
|
66
71
|
|
67
72
|
```ruby
|
73
|
+
# you must put it in a proc taking size so Graph::Function can increase it
|
68
74
|
generator = proc {|size| Rantly { dict(size) { [string, integer] } }
|
69
75
|
dict_comparison = Graph::Function::Comparison.new(generator)
|
70
|
-
# Comparison can take any number of Methods
|
76
|
+
# Comparison can take any number of Methods, but for now, 2
|
71
77
|
dict_comparison.of(method(:hash_func_one), method(:hash_func_two))
|
72
78
|
# => will output an xquartz graph
|
73
79
|
```
|
74
80
|
|
75
81
|
![comparison](spec/graph/comparison.gif)
|
76
82
|
|
77
|
-
If you want to make use of more "real" fake data, [Faker](https://github.com/stympy/faker) is included, and can be used like so:
|
83
|
+
If you want to make use of more "real" fake data, [Faker](https://github.com/stympy/faker) is also included, and can be used like so in your generators:
|
78
84
|
|
79
85
|
```ruby
|
86
|
+
# again, we need to parameterize our generator with size
|
80
87
|
faker_generator = proc {|size| Rantly(size) { call(Proc.new { Faker::Date.backward(14) }) }
|
81
88
|
# using Only here, but anything that takes a generator can take one with Faker
|
82
89
|
graph = Graph::Function::Only.new(faker_generator)
|
@@ -88,7 +95,7 @@ graph.of(method(:custom_types))
|
|
88
95
|
|
89
96
|
The only downside here is that you can't parameterize `Faker`, but you could use random generators to mix it up. Using the above example, `graph-function` won't pass anything into the `faker_generator` but the `size`, so if we want the value to change, we could use `Faker::Date.backward(proc { rand(10) }.call)`.
|
90
97
|
|
91
|
-
Check out the [spec file](spec/graph/function_spec.rb) to see all of these
|
98
|
+
Check out the [spec file](spec/graph/function_spec.rb) to see all of these or see [examples](examples/).
|
92
99
|
|
93
100
|
## Development
|
94
101
|
|
data/examples/comparing.html
CHANGED
@@ -224,28 +224,28 @@ M(5179,589);
|
|
224
224
|
L(5599,589);
|
225
225
|
M(540,3680);
|
226
226
|
L(1062,3649);
|
227
|
-
L(1584,
|
228
|
-
L(2106,
|
229
|
-
L(2628,
|
230
|
-
L(3150,
|
231
|
-
L(3671,
|
232
|
-
L(4193,
|
233
|
-
L(4715,
|
234
|
-
L(5237,
|
235
|
-
L(5759,
|
227
|
+
L(1584,3555);
|
228
|
+
L(2106,3406);
|
229
|
+
L(2628,3180);
|
230
|
+
L(3150,2902);
|
231
|
+
L(3671,2556);
|
232
|
+
L(4193,2166);
|
233
|
+
L(4715,1690);
|
234
|
+
L(5237,1168);
|
235
|
+
L(5759,587);
|
236
236
|
ctx.stroke();
|
237
237
|
ctx.closePath();
|
238
238
|
Pt(1,540,3680,60.0);
|
239
239
|
Pt(1,1062,3649,60.0);
|
240
|
-
Pt(1,1584,
|
241
|
-
Pt(1,2106,
|
242
|
-
Pt(1,2628,
|
243
|
-
Pt(1,3150,
|
244
|
-
Pt(1,3671,
|
245
|
-
Pt(1,4193,
|
246
|
-
Pt(1,4715,
|
247
|
-
Pt(1,5237,
|
248
|
-
Pt(1,5759,
|
240
|
+
Pt(1,1584,3555,60.0);
|
241
|
+
Pt(1,2106,3406,60.0);
|
242
|
+
Pt(1,2628,3180,60.0);
|
243
|
+
Pt(1,3150,2902,60.0);
|
244
|
+
Pt(1,3671,2556,60.0);
|
245
|
+
Pt(1,4193,2166,60.0);
|
246
|
+
Pt(1,4715,1690,60.0);
|
247
|
+
Pt(1,5237,1168,60.0);
|
248
|
+
Pt(1,5759,587,60.0);
|
249
249
|
Pt(1,5389,589,60.0);
|
250
250
|
} // End gp_plot_2
|
251
251
|
ctx.lineWidth = 2;
|
@@ -1,28 +1,29 @@
|
|
1
1
|
require 'graph/function'
|
2
2
|
|
3
|
+
file = File.expand_path('../comparing.html', __FILE__)
|
3
4
|
Graph::Function.configure do |config|
|
4
|
-
|
5
|
-
|
5
|
+
config.terminal = 'canvas'
|
6
|
+
config.output = file
|
6
7
|
end
|
7
8
|
|
8
9
|
def bubble_sort(array)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
10
|
+
n = array.length
|
11
|
+
loop do
|
12
|
+
swapped = false
|
13
|
+
(n-1).times do |i|
|
14
|
+
if array[i] > array[i+1]
|
15
|
+
array[i], array[i+1] = array[i+1], array[i]
|
16
|
+
swapped = true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
break if not swapped
|
20
|
+
end
|
21
|
+
array
|
21
22
|
end
|
22
23
|
|
23
24
|
def sort(array)
|
24
|
-
|
25
|
+
array.sort
|
25
26
|
end
|
26
27
|
|
27
|
-
puts
|
28
|
+
puts "output: #{file}"
|
28
29
|
Graph::Function::IntsComparison.of(method(:sort), method(:bubble_sort))
|
@@ -22,7 +22,7 @@ module Graph
|
|
22
22
|
plot.title "#{title = methods.map {|m| camel_title(m.name) }.join(', ') }"
|
23
23
|
set_up(plot)
|
24
24
|
|
25
|
-
x =
|
25
|
+
x = Graph::Function.configuration.step
|
26
26
|
pb = ProgressBar.create(title: title, total: x.size)
|
27
27
|
|
28
28
|
methods.each do |m|
|
@@ -15,7 +15,7 @@ module Graph
|
|
15
15
|
plot.title (title = "#{camel_title(method_one.name)} vs #{camel_title(method_two.name)}")
|
16
16
|
set_up(plot)
|
17
17
|
|
18
|
-
x =
|
18
|
+
x = Graph::Function.configuration.step
|
19
19
|
pb = ProgressBar.create(title: title, total: x.size)
|
20
20
|
|
21
21
|
y = x.collect do |v|
|
data/lib/graph/function/only.rb
CHANGED
data/lib/graph/function.rb
CHANGED
@@ -25,6 +25,7 @@ module Graph
|
|
25
25
|
|
26
26
|
class Configuration
|
27
27
|
attr_accessor :terminal, :output
|
28
|
+
attr_accessor :step
|
28
29
|
|
29
30
|
# defaults
|
30
31
|
# see https://github.com/rdp/ruby_gnuplot/blob/master/examples/output_image_file.rb
|
@@ -32,6 +33,7 @@ module Graph
|
|
32
33
|
def initialize
|
33
34
|
@terminal = 'x11'
|
34
35
|
@output = '.'
|
36
|
+
@step = (0..10_000).step(1000).to_a
|
35
37
|
end
|
36
38
|
end
|
37
39
|
end
|