Skip to content

Commit d4add43

Browse files
committed
Adding start of benchmarking code
1 parent 2fea075 commit d4add43

File tree

3 files changed

+402
-17
lines changed

3 files changed

+402
-17
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ A Go port of Underscore.js
3030
cd underscore-go/
3131
go test
3232

33+
# Benchmarking
34+
35+
cd underscore-go/
36+
go test -bench=.
37+
38+
- so far, only a few Array functions are benchmarked, but it's already interesting to see what's fast and what's slow
39+
3340
# TODO
3441

3542
- Port speed.js to speed\_test.go

arrays_bench_test.go

Lines changed: 366 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,366 @@
1+
package underscore
2+
3+
import (
4+
_ "github.com/markmontymark/asserts"
5+
_ "fmt"
6+
"testing"
7+
)
8+
9+
func BenchmarkFirst_a(b *testing.B) {
10+
for bi := 0; bi < b.N; bi++ {
11+
First([]T{1, 2, 3})
12+
}
13+
}
14+
func BenchmarkFirst_b(b *testing.B) {
15+
for bi := 0; bi < b.N; bi++ {
16+
FirstN([]T{1, 2, 3}, 2)
17+
}
18+
}
19+
func BenchmarkFirst_c(b *testing.B) {
20+
for bi := 0; bi < b.N; bi++ {
21+
FirstN([]T{1, 2, 3}, 5)
22+
}
23+
}
24+
func BenchmarkFirst_d(b *testing.B) {
25+
for bi := 0; bi < b.N; bi++ {
26+
Map([]T{[]T{1, 2, 3}, []T{1, 2, 3}}, func(obj T, idx T, list T) T { return First(obj.([]T)) })
27+
}
28+
}
29+
func BenchmarkFirst_e(b *testing.B) {
30+
for bi := 0; bi < b.N; bi++ {
31+
First(nil)
32+
}
33+
}
34+
35+
func BenchmarkRest_a(b *testing.B) {
36+
for bi := 0; bi < b.N; bi++ {
37+
Rest([]T{1, 2, 3})
38+
}
39+
}
40+
41+
func BenchmarkRest_b(b *testing.B) {
42+
for bi := 0; bi < b.N; bi++ {
43+
Map([]T{[]T{1, 2, 3}, []T{1, 2, 3}}, func(obj T, idx T, list T) T { return Rest(obj.([]T)) })
44+
}
45+
}
46+
47+
func BenchmarkRest_c(b *testing.B) {
48+
for bi := 0; bi < b.N; bi++ {
49+
Rest(nil)
50+
}
51+
}
52+
53+
func BenchmarkInitial_a(b *testing.B) {
54+
for bi := 0; bi < b.N; bi++ {
55+
Initial([]T{1, 2, 3})
56+
}
57+
}
58+
59+
func BenchmarkInitial_b(b *testing.B) {
60+
for bi := 0; bi < b.N; bi++ {
61+
Initial([]T{1, 2, 3}, 2)
62+
}
63+
}
64+
65+
func BenchmarkInitial_c(b *testing.B) {
66+
for bi := 0; bi < b.N; bi++ {
67+
Initial([]T{1, 2, 3}, 0)
68+
}
69+
}
70+
71+
func BenchmarkInitial_d(b *testing.B) {
72+
for bi := 0; bi < b.N; bi++ {
73+
Initial([]T{1, 2, 3}, 1)
74+
}
75+
}
76+
77+
func BenchmarkInitial_e(b *testing.B) {
78+
for bi := 0; bi < b.N; bi++ {
79+
Initial([]T{1, 2, 3}, 3)
80+
}
81+
}
82+
83+
func BenchmarkInitial_f(b *testing.B) {
84+
for bi := 0; bi < b.N; bi++ {
85+
Initial([]T{1, 2, 3}, 4)
86+
}
87+
}
88+
89+
func BenchmarkInitial_g(b *testing.B) {
90+
for bi := 0; bi < b.N; bi++ {
91+
Initial([]T{1, 2, 3}, 5)
92+
}
93+
}
94+
95+
func BenchmarkInitial_h(b *testing.B) {
96+
for bi := 0; bi < b.N; bi++ {
97+
Map([]T{[]T{1, 2, 3}, []T{1, 2, 3}}, func(obj T, idx T, list T) T { return Initial(obj.([]T), 2) })
98+
}
99+
}
100+
101+
func BenchmarkInitial_i(b *testing.B) {
102+
for bi := 0; bi < b.N; bi++ {
103+
Initial(nil)
104+
}
105+
}
106+
107+
108+
/*
109+
func BenchmarkLast(t *testing.B) {
110+
asserts.Equals(t, "can pull out the initial elements of an array",
111+
Last([]T{1, 2, 3})),
112+
"[3]")
113+
asserts.Equals(t, "can pull out the last 2 element of an array",
114+
Last([]T{1, 2, 3}, 2)), "[2 3]")
115+
116+
asserts.Equals(t, "can pull out the zeroth element of an array",
117+
Last([]T{1, 2, 3}, 0)), "[]")
118+
119+
asserts.Equals(t, "can pull out the first element of an array",
120+
Last([]T{1, 2, 3}, 1)), "[3]")
121+
122+
asserts.Equals(t, "can pull out all elements of an array",
123+
Last([]T{1, 2, 3}, 3)), "[1 2 3]")
124+
125+
asserts.Equals(t, "can pull out too many out",
126+
Last([]T{1, 2, 3}, 4)), "[1 2 3]")
127+
128+
asserts.Equals(t, "can pull out too many items out",
129+
Last([]T{1, 2, 3}, 5)), "[1 2 3]")
130+
131+
asserts.Equals(t, "works well with map",
132+
Map([]T{[]T{1, 2, 3}, []T{1, 2, 3}}, func(obj T, idx T, list T) T { return Last(obj.([]T), 2) })), "[[2 3] [2 3]]")
133+
134+
asserts.Equals(t, "works well with nil",
135+
Initial(nil)), "[]")
136+
}
137+
138+
func BenchmarkCompact(t *testing.B) {
139+
asserts.Equals(t, "can trim out all falsy values",
140+
Compact([]T{0, 1, false, 2, false, 3})), "[1 2 3]")
141+
asserts.Equals(t, "can trim out all falsy values",
142+
Compact(nil)), "[]")
143+
}
144+
145+
func BenchmarkFlatten(t *testing.B) {
146+
list := []T{1, []T{2}, []T{3, []T{[]T{[]T{4}}}}}
147+
asserts.Equals(t, "can flatten nested arrays", Flatten(list)), "[1 2 3 4]")
148+
asserts.Equals(t, "can shallowly flatten nested arrays", Flatten(list, true)),
149+
"[1 2 3 [[[4]]]]")
150+
list2 := []T{[]T{1}, []T{2}, []T{3}, []T{[]T{4}}}
151+
asserts.Equals(t, "can shallowly flatten arrays containing only other arrays",
152+
Flatten(list2, true)), "[1 2 3 [4]]")
153+
asserts.Equals(t, "can flatten arrays containing only other arrays",
154+
Flatten(list2)), "[1 2 3 4]")
155+
156+
list3 := []T{[]T{"a", "b", "c"}, []T{"d", "e", "f", "g"}}
157+
asserts.Equals(t, "can flatten arrays containing only other arrays",
158+
Flatten(list3)), "[a b c d e f g]")
159+
asserts.Equals(t, "can shallow flatten arrays containing only other arrays",
160+
Flatten(list3, true)), "[a b c d e f g]")
161+
}
162+
163+
func BenchmarkWithout(t *testing.B) {
164+
165+
list := []T{1, 2, 1, 0, 3, 1, 4}
166+
asserts.Equals(t, "can remove arbitrary ints from a list",
167+
Without(list, 0, 1)), "[2 3 4]")
168+
169+
asserts.Equals(t, "can remove all instances from an array of args from a list",
170+
Without(list, []T{0, 1})), "[2 3 4]")
171+
172+
list2 := []T{1, 2, "1", 0, 3, 1, 4}
173+
asserts.Equals(t, "can remove all instances of func args from an object",
174+
Without(list2, 0, 1)), "[2 1 3 4]")
175+
176+
asserts.Equals(t, "can remove all instances from an array of args from an object",
177+
Without(list2, []T{0, 1})), "[2 1 3 4]")
178+
179+
asserts.Equals(t, "can remove all instances from an array of args from an object",
180+
Without(list2, []T{0, "1"})), "[1 2 3 1 4]")
181+
182+
asserts.Equals(t, "can remove all instances from an array of args from an object",
183+
Without(list2, []T{0, "1", 1})), "[2 3 4]")
184+
185+
// Kludgy comparator?, go can't compare maps via identity, so stringifying each
186+
listm := []T{map[T]T{"one": 1}, map[T]T{"two": 2}}
187+
retval := Without(listm, map[T]T{"one": 1}, func(a, b T) bool {
188+
return a) == b)
189+
})
190+
asserts.Equals(t, "uses real object identity for comparisons.", retval), "[map[two:2]]")
191+
asserts.True(t, "ditto", len(retval) == 1)
192+
}
193+
194+
func BenchmarkPartition(t *testing.B) {
195+
list := []T{1, 2, 1, 0, 3, 1, 4}
196+
isOdd := func(elem T) bool {
197+
return elem.(int) % 2 != 0
198+
}
199+
asserts.Equals(t, "Can partition list ",
200+
Partition(list, isOdd)), "[[1 1 3 1] [2 0 4]]")
201+
}
202+
203+
204+
func BenchmarkUniq(t *testing.B) {
205+
list := []T{1, 2, 1, 3, 1, 4}
206+
asserts.Equals(t, "can find the unique values of an unsorted array",
207+
Uniq(list, false)), "[1 2 3 4]")
208+
209+
list2 := []T{1, 1, 1, 2, 2, 3}
210+
asserts.Equals(t, "can find the unique values of a sorted array faster",
211+
Uniq(list2, true)), "[1 2 3]")
212+
213+
list3 := []map[T]T{{"name": "moe"}, {"name": "curly"}, {"name": "larry"}, {"name": "curly"}}
214+
iterator := func(value T, key T, list T) T { return value.(map[T]T)["name"] }
215+
comparator := func(a T, b T) bool { return a.(map[T]T)["name"] == b.(map[T]T)["name"] }
216+
asserts.Equals(t, "can find the unique values of an array using a custom iterator",
217+
Uniq(list3, false, iterator, comparator)), "[map[name:moe] map[name:curly] map[name:larry]]")
218+
asserts.Equals(t, "can find the unique values of an array using a custom iterator",
219+
Map(Uniq(list3, false, iterator, comparator), iterator)), "[moe curly larry]")
220+
221+
}
222+
223+
func BenchmarkIntersection(t *testing.B) {
224+
strLessThan := func(this T, that T) bool {
225+
return this.(string) < that.(string)
226+
}
227+
stooges := []T{"moe", "curly", "larry"}
228+
leaders := []T{"moe", "groucho"}
229+
asserts.Equals(t, "can take the set intersection of two arrays",
230+
Intersection(strLessThan, stooges, leaders)), "[moe]")
231+
232+
theSixStooges := []T{"moe", "moe", "curly", "curly", "larry", "larry"}
233+
asserts.Equals(t, "returns a duplicate-free array",
234+
Intersection(strLessThan, theSixStooges, leaders)), "[moe]")
235+
}
236+
237+
func BenchmarkUnion(t *testing.B) {
238+
result := Union([]T{1, 2, 3}, []T{2, 30, 1}, []T{1, 40})
239+
asserts.Equals(t, "takes the union of a list of arrays", result), "[1 2 3 30 40]")
240+
241+
result2 := Union([]T{1, 2, 3}, []T{2, 30, 1}, []T{1, 40, []T{1}})
242+
asserts.Equals(t, "takes the union of a list of nested arrays", result2), "[1 2 3 30 40 [1]]")
243+
244+
result3 := Union(nil, []T{1, 2, 3})
245+
asserts.Equals(t, "takes the union of nil and a list of arrays", result3), "[<nil> 1 2 3]")
246+
}
247+
248+
func BenchmarkDifference(t *testing.B) {
249+
result := Difference([]T{1, 2, 3}, IdentityComparator, []T{2, 30, 40})
250+
asserts.Equals(t, "takes the difference of two arrays",
251+
result), "[1 3]")
252+
253+
result2 := Difference([]T{1, 2, 3, 4}, IdentityComparator, []T{2, 30, 40}, []T{1, 11, 111})
254+
asserts.Equals(t, "takes the difference of three arrays",
255+
result2), "[3 4]")
256+
}
257+
258+
func BenchmarkZip(t *testing.B) {
259+
260+
names := []T{"moe", "larry", "curly"}
261+
ages := []T{30, 40, 50}
262+
leaders := []T{true}
263+
264+
stooges := Zip(names, ages, leaders)
265+
asserts.Equals(t, "zipped together arrays of different lengths",
266+
stooges), "[[moe 30 true] [larry 40 <nil>] [curly 50 <nil>]]")
267+
268+
stooges2 := Zip([]T{"moe", 30, "stooge 1"}, []T{"larry", 40, "stooge 2"}, []T{"curly", 50, "stooge 3"})
269+
asserts.Equals(t, "zipped pairs",
270+
stooges2), "[[moe larry curly] [30 40 50] [stooge 1 stooge 2 stooge 3]]")
271+
272+
// In the case of difference lengths of the tuples undefineds
273+
// should be used as placeholder
274+
stooges3 := Zip([]T{"moe", 30}, []T{"larry", 40}, []T{"curly", 50, "extra data"})
275+
asserts.Equals(t, "zipped pairs with empties",
276+
stooges3), "[[moe larry curly] [30 40 50] [<nil> <nil> extra data]]")
277+
empty := Zip([]T{})
278+
asserts.Equals(t, "unzipped empty", empty), "[]")
279+
280+
empty2 := Zip([]T{})
281+
asserts.Equals(t, "unzipped empty2", empty2), "[]")
282+
}
283+
284+
func BenchmarkObject(t *testing.B) {
285+
result := Object([]T{"moe", "larry", "curly"}, []T{30, 40, 50})
286+
shouldBe := map[T]T{"moe": 30, "larry": 40, "curly": 50}
287+
asserts.Equals(t, "two arrays zipped together into an object",
288+
result), shouldBe))
289+
290+
result2 := Object([]T{"one", 1, "two", 2, "three", 3})
291+
shouldBe2 := map[T]T{"one": 1, "two": 2, "three": 3}
292+
asserts.Equals(t, "an array of pairs zipped together into an object",
293+
result2), shouldBe2))
294+
295+
result3 := Object([]T{[]T{"one", 1}, []T{"two", 2}, []T{"three", 3}})
296+
shouldBe3 := map[T]T{"one": 1, "two": 2, "three": 3}
297+
asserts.Equals(t, "an array of pairs zipped together into an object",
298+
result3), shouldBe3))
299+
300+
asserts.Nil(t, "handles nils", Object(nil))
301+
302+
stooges := map[T]T{"moe": 30, "larry": 40, "curly": 50}
303+
asserts.Equals(t, "an object converted to pairs and back to an object",
304+
stooges), Object(Pairs(stooges))))
305+
}
306+
307+
func BenchmarkIndexOf(t *testing.B) {
308+
intLessThan := func(this T, that T) bool {
309+
return this.(int) < that.(int)
310+
}
311+
numbers := []T{1, 2, 3}
312+
asserts.IntEquals(t, "can compute indexOf, even without the native function",
313+
IndexOf(numbers, 2, intLessThan), 1)
314+
315+
asserts.IntEquals(t, "handles nulls properly",
316+
IndexOf(nil, 2, intLessThan), -1)
317+
318+
num := 35
319+
numbers2 := []T{10, 20, 30, 40, 50}
320+
asserts.IntEquals(t, "35 is not in the list", IndexOf(numbers2, num, intLessThan, true), -1)
321+
num = 40
322+
asserts.IntEquals(t, "40 is in the list", IndexOf(numbers2, num, intLessThan, true), 3)
323+
324+
numbers3 := []T{1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70}
325+
num = 40
326+
asserts.IntEquals(t, "40 is in the list ", IndexOf(numbers3, num, intLessThan, true), 1)
327+
}
328+
329+
func BenchmarkLastIndexOf(t *testing.B) {
330+
numbers := []T{1, 0, 1}
331+
asserts.IntEquals(t, "lastindexof simple test", LastIndexOf(numbers, 1), 2)
332+
333+
numbers2 := []T{1, 0, 1, 0, 0, 1, 0, 0, 0}
334+
asserts.IntEquals(t, "can compute lastIndexOf", LastIndexOf(numbers2, 1), 5)
335+
asserts.IntEquals(t, "lastIndexOf the other element", LastIndexOf(numbers2, 0), 8)
336+
337+
asserts.IntEquals(t, "handles nulls properly", LastIndexOf(nil, 2), -1)
338+
339+
numbers3 := []T{1, 2, 3, 1, 2, 3, 1, 2, 3}
340+
index := LastIndexOf(numbers3, 2, 2)
341+
asserts.IntEquals(t, "supports the fromIndex argument", index, 1)
342+
343+
}
344+
345+
func BenchmarkRange(t *testing.B) {
346+
asserts.Equals(t, "range with no arguments generates an empty array",
347+
Range()), "[]")
348+
asserts.Equals(t, "range with 0 as a first argument generates an empty array",
349+
Range(0)), "[]")
350+
asserts.Equals(t, "range with a single positive argument generates an array of elements 0,1,2,...,n-1",
351+
Range(4)), "[0 1 2 3]")
352+
asserts.Equals(t, "range with two arguments a &amp; b, a&lt;b generates an array of elements a,a+1,a+2,...,b-2,b-1",
353+
Range(5, 8)), "[5 6 7]")
354+
asserts.Equals(t, "range with two arguments a &amp; b, b&lt;a generates an empty array",
355+
Range(8, 5)), "[]")
356+
asserts.Equals(t, "range with three arguments a &amp; b &amp; c, c &lt; b-a, a &lt; b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) &lt; c",
357+
Range(3, 10, 3)), "[3 6 9]")
358+
asserts.Equals(t, "range with three arguments a &amp; b &amp; c, c &gt; b-a, a &lt; b generates an array with a single element, equal to a",
359+
Range(3, 10, 15)), "[3]")
360+
asserts.Equals(t, "range with three arguments a &amp; b &amp; c, a &gt; b, c &lt; 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b",
361+
Range(12, 7, -2)), "[12 10 8]")
362+
asserts.Equals(t, "final example in the Python docs",
363+
Range(0, -10, -1)), "[0 -1 -2 -3 -4 -5 -6 -7 -8 -9]")
364+
365+
}
366+
*/

0 commit comments

Comments
 (0)