Skip to content

Commit 4d6b1c2

Browse files
ysoldakdeadprogram
authored andcommitted
tips and tricks
1 parent 1ad5d87 commit 4d6b1c2

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
title: "Tips, Tricks and Gotchas"
3+
weight: 4
4+
description: |
5+
Tips and tricks for small places.
6+
How to write efficient embedded code and avoid common mistakes.
7+
---
8+
9+
## Ensure Concurrency
10+
11+
TinyGo code runs on a single core, in a single thread (think `GOMAXPROCS=1`).
12+
Since scheduling in TinyGo is [cooperative](https://en.wikipedia.org/wiki/Cooperative_multitasking), a goroutine that never does IO or other blocking calls (f.ex. `time.Sleep()`) will lock the single available thread only for itself and never allow other goroutines to execute. In such cases, you can use `runtime.Gosched()` as a workaround.
13+
14+
```
15+
package main
16+
17+
import (
18+
"fmt"
19+
"time"
20+
"sync/atomic"
21+
"runtime"
22+
)
23+
24+
func main() {
25+
26+
var ops uint64 = 0
27+
for i := 0; i < 50; i++ {
28+
go func() {
29+
for {
30+
atomic.AddUint64(&ops, 1)
31+
runtime.Gosched()
32+
}
33+
}()
34+
}
35+
36+
time.Sleep(time.Second)
37+
38+
opsFinal := atomic.LoadUint64(&ops)
39+
fmt.Println("ops:", opsFinal)
40+
}
41+
```
42+
43+
## Save Memory
44+
45+
Use the fact [slices are descriptors of array segments](https://go.dev/blog/slices-intro#slice-internals) to save memory and avoid unnecessary allocations.
46+
Allocate once an array of maximum size you ever need and slice it in your methods to the required sizes as you go.
47+
48+
```
49+
type MyType struct {
50+
// ...other fields
51+
buf [6]byte
52+
}
53+
54+
func (t *MyType) SomeMethod() {
55+
tmpBuf := t.buf[:2] // this method needs a buffer of size 2
56+
// ... use the buffer
57+
}
58+
```
59+
60+
You may even find yourself having two or more slices pointing at diferent regions of the same array simultaneously, if you are careful.
61+
62+
```
63+
buf1 := t.buf[:2]
64+
buf2 := t.buf[2:6]
65+
```
66+
67+
For more recipes on how to avoid or minimize allocations while working with slices, please see [additional tricks](https://github.com/golang/go/wiki/SliceTricks#additional-tricks) section of [slice tricks](https://github.com/golang/go/wiki/SliceTricks) page.
68+
69+
Familiarize yourself with [heap allocation concept](../concepts/compiler-internals/heap-allocation.md) and use it to your advantage.

0 commit comments

Comments
 (0)