mirror of
https://codeberg.org/scip/golsky.git
synced 2025-12-16 12:10:58 +01:00
tried arche ecs: utter fail, needs 4.3 the time
This commit is contained in:
1
go.mod
1
go.mod
@@ -16,6 +16,7 @@ require (
|
||||
github.com/ebitenui/ebitenui v0.5.8-0.20240608175527-424f62327b21 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // 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
|
||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
|
||||
2
go.sum
2
go.sum
@@ -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/jezek/xgb v1.1.1 h1:bE/r8ZZtSv7l9gk6nU0mYx51aXrvnyb44892TwSaqS4=
|
||||
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/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/tinne26/etxt v0.0.8 h1:rjb58jkMkapRGLmhBMWnT76E/nMTXC5P1Q956BRZkoc=
|
||||
|
||||
@@ -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-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-ecs | use arche ecs, unusable | 00:14:51 |
|
||||
|
||||
5
various-tests/perf-ecs/go.mod
Normal file
5
various-tests/perf-ecs/go.mod
Normal file
@@ -0,0 +1,5 @@
|
||||
module perf
|
||||
|
||||
go 1.22
|
||||
|
||||
require github.com/mlange-42/arche v0.13.0 // indirect
|
||||
2
various-tests/perf-ecs/go.sum
Normal file
2
various-tests/perf-ecs/go.sum
Normal 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=
|
||||
145
various-tests/perf-ecs/main.go
Normal file
145
various-tests/perf-ecs/main.go
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user