enumerator-memoizing 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.
- data/README.md +53 -0
- data/Rakefile +2 -0
- data/enumerator-memoizing.gemspec +18 -0
- data/lib/enumerator/memoizing.rb +29 -0
- metadata +49 -0
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
TLDR
|
2
|
+
====
|
3
|
+
|
4
|
+
The following makes sense for memoizing concrete computed values like arrays:
|
5
|
+
```
|
6
|
+
def foo
|
7
|
+
@foo ||= costly_computation
|
8
|
+
end
|
9
|
+
```
|
10
|
+
|
11
|
+
But for enumerators it doesn't work, so instead we do this:
|
12
|
+
```
|
13
|
+
def foo
|
14
|
+
costly_computation_enumerator.memoizing.lazy
|
15
|
+
end
|
16
|
+
```
|
17
|
+
|
18
|
+
enumerator-memoizing
|
19
|
+
--------------------
|
20
|
+
|
21
|
+
This gem provides a Ruby implementation of the memoization pattern commonly found in functional programming languages. Memoization is used to save computation time by saving computed values in memory. When used in combination with [enumerable-lazy](https://github.com/yhara/enumerable-lazy) you can use ```lazy``` for deferring the computation until the elements are accessed and ```memoizing``` to allow accessing already computed values without the need to compute them again.
|
22
|
+
|
23
|
+
Example
|
24
|
+
=======
|
25
|
+
|
26
|
+
The following example makes use of lazy enumerables for computing prime numbers using an infinite list, first without and then with memoizing.
|
27
|
+
|
28
|
+
```
|
29
|
+
require 'enumerable/lazy'
|
30
|
+
require 'enumeration/memoizing'
|
31
|
+
require 'prime'
|
32
|
+
INFINITY = 1.0 / 0
|
33
|
+
|
34
|
+
all_primes = (1..INFINITY).lazy.map{|n| n**2+1}.select{|m| m.prime?}
|
35
|
+
|
36
|
+
# Test all the numbers from 1 to 28238597 -> first 500 primes
|
37
|
+
all_primes.first(500)
|
38
|
+
|
39
|
+
# Test all the numbers from 1 to 147379601 -> first 1000 primes
|
40
|
+
all_primes.first(1000)
|
41
|
+
|
42
|
+
|
43
|
+
memoizing_primes = all_primes.memoizing
|
44
|
+
|
45
|
+
# Test all the numbers from 1 to 28238597 (Memoizing the computed results) -> first 500 primes
|
46
|
+
memoizing_primes.first(500)
|
47
|
+
|
48
|
+
# Don't check 1 to 28238597 (they are memoized), Then test all the numbers from 282385978 to 147379601 -> first 1000 primes
|
49
|
+
memoizing_primes.first(1000)
|
50
|
+
|
51
|
+
# Return the memoized list of primes from 1 to 147379601, not doing any computation at all -> first 1000 primes
|
52
|
+
memoizing_primes.first(1000)
|
53
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "enumerator-memoizing"
|
6
|
+
s.version = "0.0.1"
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["Stephan Eckardt"]
|
9
|
+
s.email = ["mail@stephaneckardt.com"]
|
10
|
+
s.homepage = "https://github.com/eckardt/enumerator-memoizing"
|
11
|
+
s.summary = %q{Provides Enumerator#memoizing which memoizes computed elements of a sequence}
|
12
|
+
s.description = s.summary
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
#s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
#s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Enumerator
|
2
|
+
def memoizing
|
3
|
+
Memoizing.new(self)
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
class Enumerator::Memoizing < Enumerator
|
8
|
+
def initialize(obj, *args)
|
9
|
+
if obj.kind_of? Enumerator
|
10
|
+
base_enumerator = obj
|
11
|
+
else
|
12
|
+
base_enumerator = Enumerator.new(obj, *args)
|
13
|
+
end
|
14
|
+
|
15
|
+
memoized_sequence = []
|
16
|
+
|
17
|
+
super() do |yielder|
|
18
|
+
memoized_sequence.each do |m|
|
19
|
+
yielder << m
|
20
|
+
end
|
21
|
+
|
22
|
+
loop do
|
23
|
+
x = base_enumerator.next
|
24
|
+
memoized_sequence << x
|
25
|
+
yielder << x
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: enumerator-memoizing
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Stephan Eckardt
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-22 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Provides Enumerator#memoizing which memoizes computed elements of a sequence
|
15
|
+
email:
|
16
|
+
- mail@stephaneckardt.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- README.md
|
22
|
+
- Rakefile
|
23
|
+
- enumerator-memoizing.gemspec
|
24
|
+
- lib/enumerator/memoizing.rb
|
25
|
+
homepage: https://github.com/eckardt/enumerator-memoizing
|
26
|
+
licenses: []
|
27
|
+
post_install_message:
|
28
|
+
rdoc_options: []
|
29
|
+
require_paths:
|
30
|
+
- lib
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
32
|
+
none: false
|
33
|
+
requirements:
|
34
|
+
- - ! '>='
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ! '>='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
requirements: []
|
44
|
+
rubyforge_project:
|
45
|
+
rubygems_version: 1.8.24
|
46
|
+
signing_key:
|
47
|
+
specification_version: 3
|
48
|
+
summary: Provides Enumerator#memoizing which memoizes computed elements of a sequence
|
49
|
+
test_files: []
|