Skip to content

Commit a277d0e

Browse files
committed
Extending an array of array
1 parent 215edb3 commit a277d0e

File tree

6 files changed

+219
-4
lines changed

6 files changed

+219
-4
lines changed

src/arrayinit/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ Initializing an array can be:
55
- with a known length and make
66
- using append
77

8+
Comparison is unfair but sheds some light on the cost.
9+
The most efficient is obviously static.
10+
Append is extending the array and x5 the make().
11+
812
The method may depend on your app requirement and/or practical constraints.
913

10-
The most efficient is obviously static. It appears that append is costly.
1114

1215
`src>go test -bench=. ./arrayinit`
1316

src/arrayinit/arrayinit.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
package arrayinit
22

3-
// Luckily, it is only 10 items...
3+
// Array is known
44
func InitArrayStatic() []int {
55
a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
66
return a
77
}
8+
9+
// Array is made and filled
810
func InitArrayMake() []int {
911
a := make([]int, 10)
1012
for i := 1; i <= 10; i++ {
1113
a[i-1] = i
1214
}
1315
return a
1416
}
17+
18+
// Var is created and values appended
1519
func InitArrayAppend() []int {
1620
a := make([]int, 0)
1721
for i := 1; i <= 10; i++ {

src/arrayofarray/README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Appending elements to an array of array
2+
3+
Adding a element to an array is done using append.
4+
The array is defined as:
5+
- [][]int which is always the underlying type
6+
- []t
7+
- tt where a method is used
8+
9+
Go is strong typed and object oriented.
10+
Using a method is the most efficient even if difference can be small.
11+
12+
`src>go test -bench=. ./arrayofarray`
13+
14+
**Results**
15+
16+
```
17+
go version go1.12beta1 windows/amd64
18+
```
19+
add one cell (inc == 1)
20+
```
21+
BenchmarkUpdateArray-4 10000000 231 ns/op
22+
BenchmarkUpdateArrayType-4 20000000 154 ns/op
23+
BenchmarkUpdateArrayMethod-4 20000000 119 ns/op
24+
```
25+
26+
add 10 cells (inc == 10)
27+
```
28+
BenchmarkUpdateArray-4 1000000 1872 ns/op
29+
BenchmarkUpdateArrayType-4 1000000 1220 ns/op
30+
BenchmarkUpdateArrayMethod-4 1000000 1116 ns/op
31+
PASS
32+
```
33+
34+

src/arrayofarray/arrayofarray.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package arrayofarray
2+
3+
type (
4+
t []int
5+
tt []t
6+
)
7+
8+
const (
9+
size = 5
10+
)
11+
12+
var a = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
13+
14+
// [][]int
15+
func initArray() [][]int {
16+
ab := make([][]int, size)
17+
for i, _ := range ab {
18+
ab[i] = a[i:]
19+
}
20+
return ab
21+
}
22+
func updateArray(ab [][]int, inc int) [][]int {
23+
for k, _ := range ab {
24+
for i := 0; i < inc; i++ {
25+
// b = append(b, i): no update
26+
// ab[k] = append(b, i): last update
27+
ab[k] = append(ab[k], i)
28+
}
29+
}
30+
return ab
31+
}
32+
33+
// []t
34+
func initArrayType() []t {
35+
ab := make([]t, size)
36+
for i, _ := range ab {
37+
ab[i] = a[i:]
38+
}
39+
return ab
40+
}
41+
func updateArrayType(ab []t, inc int) []t {
42+
for k, _ := range ab {
43+
for i := 0; i < inc; i++ {
44+
ab[k] = append(ab[k], i)
45+
}
46+
}
47+
return ab
48+
}
49+
50+
// tt
51+
func initArrayTyped() tt {
52+
ab := make([]t, size)
53+
for i, _ := range ab {
54+
ab[i] = a[i:]
55+
}
56+
return ab
57+
}
58+
func (ab *tt) updateArrayMethod(inc int) {
59+
abt := *ab
60+
for k, _ := range abt {
61+
for i := 0; i < inc; i++ {
62+
abt[k] = append(abt[k], i)
63+
}
64+
}
65+
*ab = abt
66+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package arrayofarray
2+
3+
import (
4+
"testing"
5+
)
6+
7+
const (
8+
inc = 1
9+
want = 10 * size
10+
)
11+
12+
// [][]int
13+
func llen(ab [][]int) (l int) {
14+
for _, a := range ab {
15+
l += len(a)
16+
}
17+
return
18+
}
19+
func TestInitArray(t *testing.T) {
20+
want := want - size*(size-1)/2
21+
if got := initArray(); llen(got) != want {
22+
t.Fatalf("want %d, got %d\n %v", want, llen(got), got)
23+
}
24+
}
25+
func TestUpdateArray(t *testing.T) {
26+
want := want - size*(size-1)/2 + inc*size
27+
if got := updateArray(initArray(), inc); llen(got) != want {
28+
t.Fatalf("want %d, got %d\n %v", want, llen(got), got)
29+
} else {
30+
for _, a := range got {
31+
if gotv := a[len(a)-inc]; gotv != 0 {
32+
t.Fatalf("want 0, got %d in %v", gotv, a)
33+
}
34+
}
35+
}
36+
37+
}
38+
39+
// []t
40+
func llent(ab []t) (l int) {
41+
for _, a := range ab {
42+
l += len(a)
43+
}
44+
45+
return
46+
}
47+
func TestUpdateArrayType(t *testing.T) {
48+
want := want - size*(size-1)/2 + inc*size
49+
if got := updateArrayType(initArrayType(), inc); llent(got) != want {
50+
t.Fatalf("want %d, got %d\n %v", want, llent(got), got)
51+
} else {
52+
for _, a := range got {
53+
if gotv := a[len(a)-inc]; gotv != 0 {
54+
t.Fatalf("want 0, got %d in %v", gotv, a)
55+
}
56+
}
57+
}
58+
}
59+
60+
// tt
61+
func (ab tt) llen() (l int) {
62+
for _, a := range ab {
63+
l += len(a)
64+
}
65+
return
66+
}
67+
func TestInitArrayType(t *testing.T) {
68+
want := want - size*(size-1)/2
69+
if got := initArrayTyped(); got.llen() != want {
70+
t.Fatalf("want %d, got %d\n %v", want, got.llen(), got)
71+
}
72+
}
73+
func TestUpdateArrayMethod(t *testing.T) {
74+
var tb tt
75+
tb = initArrayType()
76+
want := want - size*(size-1)/2 + inc*size
77+
tb.updateArrayMethod(inc)
78+
if ll := tb.llen(); ll != want {
79+
t.Fatalf("want %d, got %d\n %v", want, ll, tb)
80+
} else {
81+
for _, a := range tb {
82+
if gotv := a[len(a)-inc]; gotv != 0 {
83+
t.Fatalf("want 0, got %d in %v", gotv, a)
84+
}
85+
}
86+
}
87+
}
88+
89+
// w/o the for loop, no benchmarking occurs because of optimization
90+
func BenchmarkUpdateArray(b *testing.B) {
91+
tb := initArray()
92+
for n := 0; n < b.N; n++ {
93+
updateArray(tb, inc)
94+
}
95+
}
96+
func BenchmarkUpdateArrayType(b *testing.B) {
97+
tb := initArrayType()
98+
for n := 0; n < b.N; n++ {
99+
updateArrayType(tb, inc)
100+
}
101+
}
102+
func BenchmarkUpdateArrayMethod(b *testing.B) {
103+
var tb tt
104+
tb = initArrayType()
105+
for n := 0; n < b.N; n++ {
106+
tb.updateArrayMethod(inc)
107+
}
108+
}

src/arraysstruct/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ You need to maintain related data using an ordinary string key:
99

1010
**Results**
1111

12-
Arrays are slightly the faster.
13-
An array of struct has a similar performance with the advantage of stronger typing.
12+
Arrays are slightly faster.
13+
Performance of an array of struct is similar with the advantage of stronger typing.
1414
The map is 30% more expensive.
1515

1616
```

0 commit comments

Comments
 (0)