Added 'value' field to number based on conjectures related to addition. See my
chapter 2 and 3 notes. This allowed a binary search of the universe rather than
a linear search.
Benchmarking command:
time ./ch1-breeding-numbers -generations 13 -silent
Before:
382.156u 3.945s 5:41.96 112.9% 0+0k 40+66io 7pf+0w
After:
59.828u 3.247s 0:30.70 205.4% 0+0k 1+0io 0pf+0w
"log"
"os"
"runtime/pprof"
"log"
"os"
"runtime/pprof"
}
func (u *surrealUniverse) getIndex(num surrealNumber) int {
}
func (u *surrealUniverse) getIndex(num surrealNumber) int {
- for i := 0; i < len(u.numbers); i++ {
- if num.identifier == u.numbers[i].identifier {
- return i
- }
- }
- return -1 // This should be unreachable.
+ // Since getIndex() is only ever called on 'num' which already exists in
+ // the universe, we return the result directly, without bothering to
+ // confirm an exact match.
+ //
+ // Also, we can get away with a direct comparison of these floating point
+ // numbers since there will be an exact match, guaranteed since 'num' is
+ // already in the universe.
+ return sort.Search(u.cardinality(), func(i int) bool {return u.numbers[i].value >= num.value})
}
func (u *surrealUniverse) cardinality() int {
}
func (u *surrealUniverse) cardinality() int {
switch ancestorCount {
case 0:
if u.cardinality() == 0 {
switch ancestorCount {
case 0:
if u.cardinality() == 0 {
num.identifier = u.nextUniqueID
u.nextUniqueID++
u.numbers = append(u.numbers, num)
}
case 1:
num.identifier = u.nextUniqueID
u.nextUniqueID++
u.numbers = append(u.numbers, num)
}
case 1:
- if num.leftSet.cardinality() == 1{
+ if num.leftSet.cardinality() == 1 {
index := u.getIndex(num.leftSet.members[0])
index := u.getIndex(num.leftSet.members[0])
- num.identifier = u.nextUniqueID
- u.nextUniqueID++
if index+1 == u.cardinality() {
if index+1 == u.cardinality() {
+ num.value = u.numbers[u.cardinality()-1].value + 1.0
+ num.identifier = u.nextUniqueID
+ u.nextUniqueID++
u.numbers = append(u.numbers, num)
}
} else {
index := u.getIndex(num.rightSet.members[0])
u.numbers = append(u.numbers, num)
}
} else {
index := u.getIndex(num.rightSet.members[0])
- num.identifier = u.nextUniqueID
- u.nextUniqueID++
+ num.value = u.numbers[0].value - 1.0
+ num.identifier = u.nextUniqueID
+ u.nextUniqueID++
u.numbers = append(u.numbers[:1], u.numbers...)
u.numbers[0] = num
}
u.numbers = append(u.numbers[:1], u.numbers...)
u.numbers[0] = num
}
leftIndex := u.getIndex(num.leftSet.members[0])
rightIndex := u.getIndex(num.rightSet.members[0])
if leftIndex+1 == rightIndex {
leftIndex := u.getIndex(num.leftSet.members[0])
rightIndex := u.getIndex(num.rightSet.members[0])
if leftIndex+1 == rightIndex {
+ num.value = (num.leftSet.members[0].value + num.rightSet.members[0].value) / 2
num.identifier = u.nextUniqueID
u.nextUniqueID++
u.numbers = append(u.numbers[:rightIndex+1], u.numbers[rightIndex:]...)
num.identifier = u.nextUniqueID
u.nextUniqueID++
u.numbers = append(u.numbers[:rightIndex+1], u.numbers[rightIndex:]...)
type surrealNumber struct {
leftSet surrealSet
rightSet surrealSet
type surrealNumber struct {
leftSet surrealSet
rightSet surrealSet
identifier uint
generation int
}
identifier uint
generation int
}
var universe surrealUniverse
universe.nextUniqueID = 0
fmt.Println("Seeding generation 0 by hand.")
var universe surrealUniverse
universe.nextUniqueID = 0
fmt.Println("Seeding generation 0 by hand.")
- universe.insert(surrealNumber{surrealSet{}, surrealSet{}, 0, 0})
+ universe.insert(surrealNumber{surrealSet{}, surrealSet{}, 0.0, 0, 0})
// Breed however many generations of numbers were requested by the user and
// add them all to the universe.
// Breed however many generations of numbers were requested by the user and
// add them all to the universe.
var leftSet, rightSet surrealSet
leftSet.insert(universe.numbers[i], universe)
rightSet.insert(universe.numbers[j], universe)
var leftSet, rightSet surrealSet
leftSet.insert(universe.numbers[i], universe)
rightSet.insert(universe.numbers[j], universe)
- newSurrealNumber := surrealNumber{leftSet,rightSet,0,generation}
+ newSurrealNumber := surrealNumber{leftSet,rightSet,0.0,0,generation}
numbers = append(numbers, newSurrealNumber)
}
}
numbers = append(numbers, newSurrealNumber)
}
}
for i := 0; i < universe.cardinality(); i++ {
var tempSet surrealSet
tempSet.insert(universe.numbers[i], universe)
for i := 0; i < universe.cardinality(); i++ {
var tempSet surrealSet
tempSet.insert(universe.numbers[i], universe)
- newSurrealNumber := surrealNumber{tempSet,surrealSet{},0,generation}
+ newSurrealNumber := surrealNumber{tempSet,surrealSet{},0.0,0,generation}
numbers = append(numbers, newSurrealNumber)
numbers = append(numbers, newSurrealNumber)
- newSurrealNumber = surrealNumber{surrealSet{},tempSet,0,generation}
+ newSurrealNumber = surrealNumber{surrealSet{},tempSet,0.0,0,generation}
numbers = append(numbers, newSurrealNumber)
}
numbers = append(numbers, newSurrealNumber)
}