diff --git a/.ci/Dockerfile b/.ci/Dockerfile index a7960fa3..c655a2d6 100644 --- a/.ci/Dockerfile +++ b/.ci/Dockerfile @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.18-alpine AS builder +FROM golang:1.19-alpine@sha256:276692412aea6f9dd6cdc5725b2f1c05bef8df7223811afbc6aa16294e2903f9 AS builder # Install dependencies RUN apk add --no-cache git bash curl zip diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 14201571..6f7974fb 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -20,6 +20,10 @@ on: pull_request: branches: [main] +env: + GO_VERSION: 1.19 + OAPI_CODEGEN_VERSION: v1.12.4 + jobs: go: name: Check go tools build @@ -31,7 +35,7 @@ jobs: - name: Setup Go environment uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: - go-version: 1.18 + go-version: ${{ env.GO_VERSION }} - name: Check if index-generator build is working run: cd index/generator && bash ./build.sh @@ -45,7 +49,7 @@ jobs: - name: Check index-server code generation run: | export GOPATH=$(go env GOPATH) - go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.12.4 + go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@${{ env.OAPI_CODEGEN_VERSION }} bash index/server/codegen.sh GEN_DIFFS=$(git diff --name-only --diff-filter=ACMRT | grep .gen.go$ | xargs) if [[ ! -z "${GEN_DIFFS}" ]] @@ -83,7 +87,7 @@ jobs: - name: Setup Go environment uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: - go-version: 1.18 + go-version: ${{ env.GO_VERSION }} - name: Check license run: | @@ -102,7 +106,7 @@ jobs: run: | cd index/server export GOPATH=$(go env GOPATH) - go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.12.4 + go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@${{ env.OAPI_CODEGEN_VERSION }} bash ./build.sh - name: Test index server @@ -127,7 +131,7 @@ jobs: - name: Setup Go environment uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: - go-version: 1.18 + go-version: ${{ env.GO_VERSION }} - name: Setup Minikube uses: manusa/actions-setup-minikube@3856c6fa039819f1c8e7e248b1fc5a8564e354c9 # v2.9.0 with: @@ -139,7 +143,7 @@ jobs: - name: Run the devfile registry integration tests run: | export GOPATH=$(go env GOPATH) - go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.12.4 + go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@${{ env.OAPI_CODEGEN_VERSION }} bash .ci/run_tests_minikube_linux.sh test_staging: @@ -151,7 +155,7 @@ jobs: - name: Setup Go environment uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: - go-version: 1.18 + go-version: ${{ env.GO_VERSION }} - name: Run the devfile registry integration tests run: | # Run the integration tests diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml index 015cdc1d..2c377a7d 100644 --- a/.github/workflows/codecov.yaml +++ b/.github/workflows/codecov.yaml @@ -28,7 +28,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: - go-version: 1.18 + go-version: 1.19 - name: Run tests run: cd index/server && go test ./... -coverprofile cover.out - name: Codecov diff --git a/.github/workflows/pushimage-next.yaml b/.github/workflows/pushimage-next.yaml index 0629ba4a..3d6a9182 100644 --- a/.github/workflows/pushimage-next.yaml +++ b/.github/workflows/pushimage-next.yaml @@ -30,7 +30,7 @@ jobs: - name: Setup Go environment uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: - go-version: 1.18 + go-version: 1.19 - name: Login to Quay uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0 with: diff --git a/README.md b/README.md index 3a1436c3..9de1f3e0 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@
Benchmark | go-toml v1 | BurntSushi/toml |
---|---|---|
Marshal/HugoFrontMatter-2 | 1.9x | 1.9x |
Marshal/ReferenceFile/map-2 | 1.7x | 1.8x |
Marshal/ReferenceFile/struct-2 | 2.2x | 2.5x |
Unmarshal/HugoFrontMatter-2 | 2.9x | 2.9x |
Unmarshal/ReferenceFile/map-2 | 2.6x | 2.9x |
Unmarshal/ReferenceFile/struct-2 | 4.4x | 5.3x |
The table above has the results of the most common use-cases. The table below +contains the results of all benchmarks, including unrealistic ones. It is +provided for completeness.
+ +Benchmark | go-toml v1 | BurntSushi/toml |
---|---|---|
Marshal/SimpleDocument/map-2 | 1.8x | 2.9x |
Marshal/SimpleDocument/struct-2 | 2.7x | 4.2x |
Unmarshal/SimpleDocument/map-2 | 4.5x | 3.1x |
Unmarshal/SimpleDocument/struct-2 | 6.2x | 3.9x |
UnmarshalDataset/example-2 | 3.1x | 3.5x |
UnmarshalDataset/code-2 | 2.3x | 3.1x |
UnmarshalDataset/twitter-2 | 2.5x | 2.6x |
UnmarshalDataset/citm_catalog-2 | 2.1x | 2.2x |
UnmarshalDataset/canada-2 | 1.6x | 1.3x |
UnmarshalDataset/config-2 | 4.3x | 3.2x |
[Geo mean] | 2.7x | 2.8x |
This table can be generated with ./ci.sh benchmark -a -html
.
Benchmark | go-toml v1 | BurntSushi/toml |
---|---|---|
{} | {} | {} |
The table above has the results of the most common use-cases. The table below +contains the results of all benchmarks, including unrealistic ones. It is +provided for completeness.
""") +printtable(below) +print('This table can be generated with ./ci.sh benchmark -a -html
.
stdlib |
+conc |
+
---|---|
+ +```go +type caughtPanicError struct { + val any + stack []byte +} + +func (e *caughtPanicError) Error() string { + return fmt.Sprintf( + "panic: %q\n%s", + e.val, + string(e.stack) + ) +} + +func main() { + done := make(chan error) + go func() { + defer func() { + if v := recover(); v != nil { + done <- &caughtPanicError{ + val: v, + stack: debug.Stack() + } + } else { + done <- nil + } + }() + doSomethingThatMightPanic() + }() + err := <-done + if err != nil { + panic(err) + } +} +``` + | ++ +```go +func main() { + var wg conc.WaitGroup + wg.Go(doSomethingThatMightPanic) + // panics with a nice stacktrace + wg.Wait() +} +``` + | +
stdlib |
+conc |
+
---|---|
+ +```go +func main() { + var wg sync.WaitGroup + for i := 0; i < 10; i++ { + wg.Add(1) + go func() { + defer wg.Done() + // crashes on panic! + doSomething() + }() + } + wg.Wait() +} +``` + | ++ +```go +func main() { + var wg conc.WaitGroup + for i := 0; i < 10; i++ { + wg.Go(doSomething) + } + wg.Wait() +} +``` + | +
stdlib |
+conc |
+
---|---|
+ +```go +func process(stream chan int) { + var wg sync.WaitGroup + for i := 0; i < 10; i++ { + wg.Add(1) + go func() { + defer wg.Done() + for elem := range stream { + handle(elem) + } + }() + } + wg.Wait() +} +``` + | ++ +```go +func process(stream chan int) { + p := pool.New().WithMaxGoroutines(10) + for elem := range stream { + elem := elem + p.Go(func() { + handle(elem) + }) + } + p.Wait() +} +``` + | +
stdlib |
+conc |
+
---|---|
+ +```go +func process(values []int) { + feeder := make(chan int, 8) + + var wg sync.WaitGroup + for i := 0; i < 10; i++ { + wg.Add(1) + go func() { + defer wg.Done() + for elem := range feeder { + handle(elem) + } + }() + } + + for _, value := range values { + feeder <- value + } + close(feeder) + wg.Wait() +} +``` + | ++ +```go +func process(values []int) { + iter.ForEach(values, handle) +} +``` + | +
stdlib |
+conc |
+
---|---|
+ +```go +func concMap( + input []int, + f func(int) int, +) []int { + res := make([]int, len(input)) + var idx atomic.Int64 + + var wg sync.WaitGroup + for i := 0; i < 10; i++ { + wg.Add(1) + go func() { + defer wg.Done() + + for { + i := int(idx.Add(1) - 1) + if i >= len(input) { + return + } + + res[i] = f(input[i]) + } + }() + } + wg.Wait() + return res +} +``` + | ++ +```go +func concMap( + input []int, + f func(*int) int, +) []int { + return iter.Map(input, f) +} +``` + | +
stdlib |
+conc |
+
---|---|
+ +```go +func mapStream( + in chan int, + out chan int, + f func(int) int, +) { + tasks := make(chan func()) + taskResults := make(chan chan int) + + // Worker goroutines + var workerWg sync.WaitGroup + for i := 0; i < 10; i++ { + workerWg.Add(1) + go func() { + defer workerWg.Done() + for task := range tasks { + task() + } + }() + } + + // Ordered reader goroutines + var readerWg sync.WaitGroup + readerWg.Add(1) + go func() { + defer readerWg.Done() + for result := range taskResults { + item := <-result + out <- item + } + }() + + // Feed the workers with tasks + for elem := range in { + resultCh := make(chan int, 1) + taskResults <- resultCh + tasks <- func() { + resultCh <- f(elem) + } + } + + // We've exhausted input. + // Wait for everything to finish + close(tasks) + workerWg.Wait() + close(taskResults) + readerWg.Wait() +} +``` + | ++ +```go +func mapStream( + in chan int, + out chan int, + f func(int) int, +) { + s := stream.New().WithMaxGoroutines(10) + for elem := range in { + elem := elem + s.Go(func() stream.Callback { + res := f(elem) + return func() { out <- res } + }) + } + s.Wait() +} +``` + | +
=p for i =p for iWelcome, Ginner!
-
-