graph-function 0.1.1 → 0.1.2
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.
- 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
|

|
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
|

|
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
|