tried arche ecs: utter fail, needs 4.3 the time

This commit is contained in:
2024-06-12 20:01:30 +02:00
parent 39da34cb5c
commit 45e5fc7e3b
6 changed files with 156 additions and 0 deletions

1
go.mod
View File

@@ -16,6 +16,7 @@ require (
github.com/ebitenui/ebitenui v0.5.8-0.20240608175527-424f62327b21 // indirect github.com/ebitenui/ebitenui v0.5.8-0.20240608175527-424f62327b21 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/jezek/xgb v1.1.1 // indirect github.com/jezek/xgb v1.1.1 // indirect
github.com/mlange-42/arche v0.13.0 // indirect
github.com/tinne26/etxt v0.0.8 // indirect github.com/tinne26/etxt v0.0.8 // indirect
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
golang.org/x/sync v0.7.0 // indirect golang.org/x/sync v0.7.0 // indirect

2
go.sum
View File

@@ -16,6 +16,8 @@ github.com/hajimehoshi/ebiten/v2 v2.7.4 h1:X+heODRQ3Ie9F9QFjm24gEZqQd5FSfR9XuT2X
github.com/hajimehoshi/ebiten/v2 v2.7.4/go.mod h1:H2pHVgq29rfm5yeQ7jzWOM3VHsjo7/AyucODNLOhsVY= github.com/hajimehoshi/ebiten/v2 v2.7.4/go.mod h1:H2pHVgq29rfm5yeQ7jzWOM3VHsjo7/AyucODNLOhsVY=
github.com/jezek/xgb v1.1.1 h1:bE/r8ZZtSv7l9gk6nU0mYx51aXrvnyb44892TwSaqS4= github.com/jezek/xgb v1.1.1 h1:bE/r8ZZtSv7l9gk6nU0mYx51aXrvnyb44892TwSaqS4=
github.com/jezek/xgb v1.1.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk= github.com/jezek/xgb v1.1.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
github.com/mlange-42/arche v0.13.0 h1:ef0fu9qC2KIr8wIlVs+CgeQ5CSUJ8A1Hut6nXYdf+xk=
github.com/mlange-42/arche v0.13.0/go.mod h1:bFktKnvGDj2kP01xar79z0hKwGHdnoaEZR8HWmJkIyU=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/tinne26/etxt v0.0.8 h1:rjb58jkMkapRGLmhBMWnT76E/nMTXC5P1Q956BRZkoc= github.com/tinne26/etxt v0.0.8 h1:rjb58jkMkapRGLmhBMWnT76E/nMTXC5P1Q956BRZkoc=

View File

@@ -9,3 +9,4 @@ Running with 1500x1500 grid 5k times
| perf-2dim-pointers-array | same as above but array of neighbors instead of slice | 00:02:40 | | perf-2dim-pointers-array | same as above but array of neighbors instead of slice | 00:02:40 |
| perf-2dim-pointers-all-array | use arrays for everything, static 1500x1500 | infinite, aborted | | perf-2dim-pointers-all-array | use arrays for everything, static 1500x1500 | infinite, aborted |
| perf-1dim | use 1d grid of bools, access using y*x, no further tuning | 00:03:24 | | perf-1dim | use 1d grid of bools, access using y*x, no further tuning | 00:03:24 |
| perf-ecs | use arche ecs, unusable | 00:14:51 |

View File

@@ -0,0 +1,5 @@
module perf
go 1.22
require github.com/mlange-42/arche v0.13.0 // indirect

View File

@@ -0,0 +1,2 @@
github.com/mlange-42/arche v0.13.0 h1:ef0fu9qC2KIr8wIlVs+CgeQ5CSUJ8A1Hut6nXYdf+xk=
github.com/mlange-42/arche v0.13.0/go.mod h1:bFktKnvGDj2kP01xar79z0hKwGHdnoaEZR8HWmJkIyU=

View File

@@ -0,0 +1,145 @@
package main
import (
"fmt"
"log"
"math/rand"
"os"
"runtime/pprof"
"github.com/mlange-42/arche/ecs"
"github.com/mlange-42/arche/generic"
)
const (
max int = 1500
loops int = 5000
density int = 8
debug bool = false
)
// components
type Pos struct {
X, Y, GridX, GridY int
}
type Cell struct {
State bool
Neighbors [8]ecs.Entity
}
type ECS struct {
World *ecs.World
Filter *generic.Filter2[Pos, Cell]
Map *generic.Map2[Pos, Cell]
}
func (cell *Cell) NeighborCount(ECS *ECS) int {
sum := 0
for _, neighbor := range cell.Neighbors {
if ECS.World.Alive(neighbor) {
_, cel := ECS.Map.Get(neighbor)
if cel.State {
sum++
}
}
}
return sum
}
func Loop(ECS *ECS) {
c := 0
for i := 0; i < loops; i++ {
query := ECS.Filter.Query(ECS.World)
for query.Next() {
_, cel := query.Get()
if cel.State && cel.NeighborCount(ECS) > 1 {
c = 1
}
}
}
if c > 1 {
c = 0
}
}
func SetupWorld() *ECS {
world := ecs.NewWorld()
builder := generic.NewMap2[Pos, Cell](&world)
// we need a temporary grid in order to find out neighbors
grid := [max][max]ecs.Entity{}
// setup entities
for y := 0; y < max; y++ {
for x := 0; x < max; x++ {
e := builder.New()
pos, cell := builder.Get(e)
pos.X = x
pos.Y = y // pos.GridX = x*cellsize
cell.State = false
if rand.Intn(density) == 1 {
cell.State = true
}
// store to tmp grid
grid[y][x] = e
}
}
// global filter
filter := generic.NewFilter2[Pos, Cell]()
query := filter.Query(&world)
for query.Next() {
pos, cel := query.Get()
n := 0
for x := -1; x < 2; x++ {
for y := -1; y < 2; y++ {
XX := pos.X + x
YY := pos.Y + y
if XX < 0 || XX >= max || YY < 0 || YY >= max {
continue
}
if pos.X != XX || pos.Y != YY {
cel.Neighbors[n] = grid[XX][YY]
n++
}
}
}
}
return &ECS{World: &world, Filter: filter, Map: &builder}
}
func main() {
// enable cpu profiling. Do NOT use q to stop the game but
// close the window to get a profile
fd, err := os.Create("cpu.profile")
if err != nil {
log.Fatal(err)
}
defer fd.Close()
pprof.StartCPUProfile(fd)
defer pprof.StopCPUProfile()
// init
fmt.Print("Setup ... ")
ECS := SetupWorld()
fmt.Println("done")
fmt.Println(ECS.World.Stats())
// main loop
Loop(ECS)
}