Slow map generator
[1/5] from: oliva:david:seznam:cz at: 8-Nov-2001 19:39
Slow map generator
==================
I know, that Rebol is not the best tool for things like that, but I cannot help myself...
...Does anybody know how to speed up the script below somehow?
What's so slow? I'm going thru a matrix (image in this example) to create random heights
of the map and then several times to make somethink like erosion of the land. I need
to find adjacent cells in the matrix and that's the slow thing I think:-)
Holger, do you think it would be posible to make some native support for that kind of
operations (matrix neighbours) I would find it useful in more of my scripts (in the RBox2
as well) - it's always the slowest part?
thank you, Oldes
;----------------------------------
rebol [title: "map generator test"]
map_size_x: 200
map_size_y: 200
random/seed 1000
height_map: make block! (map_size_x * map_size_y)
set-pixel: func [
im [image!]
x [integer!]
y [integer!]
color [tuple!]
/local x-siz y-siz siz
][
x-siz: im/size/x
y-siz: im/size/y
poke im (y-siz - y * x-siz + x) color
]
t: now/precise/time
for y 1 map_size_y 1 [
for x 1 map_size_x 1 [
insert tail height_map (random 40 + ((500 - abs (map_size_y / 2 - y)) / 10))
]
]
probe t: now/time/precise - t
map_adjust_y: func[y][either y < 1 [map_size_y][either y > map_size_y [1][y]]]
map_adjust_x: func[x][either x < 1 [map_size_x][either x > map_size_x [1][x]]]
get_hmap: func[x y][pick height_map ((y - 1) * map_size_y + x)]
set_hmap: func[x y val][poke height_map ((y - 1) * map_size_y + x) val]
smooth_map: func[][
for y 1 map_size_y 1 [
my: map_adjust_y (y - 1)
py: map_adjust_y (y + 1)
for x 1 map_size_x 1 [
mx: map_adjust_x (x - 1)
px: map_adjust_x (x + 1)
a: 2 * get_hmap x y
a: a + get_hmap px my
a: a + get_hmap mx my
a: a + get_hmap mx py
a: a + get_hmap px py
a: a + get_hmap x my
a: a + get_hmap mx y
a: a + get_hmap x py
a: a + get_hmap px y
a: max (a - 30 + random 60) 0
set_hmap x y a / 10
]
]
]
peeks: make block! 40
loop 20 [
x: random map_size_x
y: random map_size_y
insert tail peeks reduce [x y]
set_hmap x y 255
x: x - 1
set_hmap x y min (60 + get_hmap x y ) 255
y: y - 1
set_hmap x y min (60 + get_hmap x y ) 255
]
t: now/precise/time
loop 8 [smooth_map] ;really slow loop (map erosion)
probe t: now/time/precise - t
map-img: make image! to-pair reduce [map_size_x map_size_y]
forall height_map [
poke map-img index? height_map 1.1.1 * first height_map
]
foreach [x y] peeks [set-pixel map-img x y 255.100.0]
height_map: head height_map
view/options center-face layout [origin 0x0 image map-img effect [luma 10 contrast]]
[no-border no-title]
[2/5] from: steve:shireman:semaxwireless at: 8-Nov-2001 13:40
Oliva,
Don't know why it's slow, but thanks for sharing...;-)
My design for a map datatype is slightly different than this. Let
me play with it a while...
Steve Shireman
[oliva--david--seznam--cz] wrote:
[3/5] from: ryanc::iesco-dms::com at: 8-Nov-2001 11:37
Hey
Here is where all the time is wasted, so its a good place to start:
for x 1 map_size_x 1 [
mx: map_adjust_x (x - 1)
px: map_adjust_x (x + 1)
a: 2 * get_hmap x y
a: a + get_hmap px my
a: a + get_hmap mx my
a: a + get_hmap mx py
a: a + get_hmap px py
a: a + get_hmap x my
a: a + get_hmap mx y
a: a + get_hmap x py
a: a + get_hmap px y
a: max (a - 30 + random 60) 0
set_hmap x y a / 10
]
I would suggest trying something looking like this:
for x 1 map_size_x 1 [
mx: either x - 1< 1 [map_size_x][either x - 1 > map_size_x [1][x - 1]]
px: either x + 1< 1 [map_size_x][either x + 1 > map_size_x [1][x + 1]]
a: 2 * map/:x/:y
a: a + map/:px/:my + map/:mx/:my + map/:mx/:py +
map/:px/:py + map/:x/:my + map/:mx/:y + map/:x/:py +
map/:px/:y
a: max (a - 30 + random 60) 0
poke map/:x y a / 10
]
The idea is that you can problably get a gain by using a x/y mapping scheme in this case.
It should make up for remapping the image when done I could optimize a bit more, keeping
it linear, but maybe later...
--Ryan
[4/5] from: ryanc:iesco-dms at: 8-Nov-2001 13:16
I optimized a few more little things...
repeat x map_size_x [ ; 'repeat was much faster than 'for in my most recent tests.
mx: pick mx-table x ; lookup tables instead for a sizable gain
px: pick px-table x
; I missed a little last time here. Continious math operations are real fast.
a: 2 * map/:x/:y + map/:px/:my + map/:mx/:my +
map/:mx/:py + map/:px/:py + map/:x/:my +
map/:mx/:y + map/:x/:py + map/:px/:y
a: max 0 a - 30 + random 60 ; a little switcheroo here for a minor gain
poke pick map x y a / 10 ; faster yet
]
That should be much faster. --Ryan
Ryan Cole wrote:
> Hey
> Here is where all the time is wasted, so its a good place to start:
<<quoted lines omitted: 30>>
> [rebol-request--rebol--com] with "unsubscribe" in the
> subject, without the quotes.
--
Ryan Cole
Programmer Analyst
www.iesco-dms.com
707-468-5400
The contradiction so puzzling to the ordinary way
of thinking comes from the fact that we have to use
language to communicate our inner experience
which in its very nature transcends lingistics.
-D.T. Suzuki
[5/5] from: nitsch-lists:netcologne at: 9-Nov-2001 10:30
RE: [REBOL] Slow map generator
[oliva--david--seznam--cz] wrote:
> Slow map generator
> > I know, that Rebol is not the best tool for things like that, but I cannot help myself...
<<quoted lines omitted: 3>>
> thank you, Oldes
> ;----------------------------------
Hi Oldes!
speeded it up 3*, from 45 sec down to 15 sec now (350Mhz).
not really fast, but could give 2-sec framerates.
well, gives that rate now.. run script :-)
note it keeps the wall-fields constant now,
that way i drop border-checking.
-Volker
rebol [title: "stars coming out"]
;map_size_x: 10 map_size_y: 10
map_size_x: 200 map_size_y: 200
random/seed 1000
height_map: make block! (map_size_x * map_size_y)
set-pixel: func [
im [image!]
x [integer!]
y [integer!]
color [tuple!]
/local x-siz y-siz siz
] [
x-siz: im/size/x
y-siz: im/size/y
poke im (y-siz - y * x-siz + x) color
]
t: now/precise/time
for y 1 map_size_y 1 [
for x 1 map_size_x 1 [
insert tail height_map (random 40 + ((500 - abs (map_size_y / 2 - y)) / 10))
]
]
;probe t: now/time/precise - t
map_adjust_y: func [y] [either y < 1 [map_size_y] [either y > map_size_y [1] [y]]]
map_adjust_x: func [x] [either x < 1 [map_size_x] [either x > map_size_x [1] [x]]]
get_hmap: func [x y] [pick height_map ((y - 1) * map_size_y + x)]
set_hmap: func [x y val] [poke height_map ((y - 1) * map_size_y + x) val]
;we use skip as implicit + 1
map2: copy/deep height_map
smooth_map: func [] [
repeat y-1 map_size_y - 2 [
c.y-1: at height_map y-1 - 1 * map_size_y
c.y: skip c.y-1 map_size_y
c.y+1: skip c.y map_size_y
repeat x-1 map_size_x - 2 [
x: x-1 + 1 x+1: x-1 + 2
a: 2 * c.y/:x
+ c.y-1/:x-1 + c.y-1/:x + c.y-1/:x+1
+ c.y/:x-1 + c.y/:x+1
+ c.y+1/:x-1 + c.y+1/:x + c.y+1/:x+1
;d: at map2 index? c.y
;poke d x 0.1 * max (a - 30 + random 60) 0
poke c.y x 0.1 * max (a - 30 + random 60) 0
]
]
;set [height_map map2] reduce [map2 height_map]
]
peeks: make block! 40
do [
loop 20 [
x: random map_size_x
y: random map_size_y
insert tail peeks reduce [x y]
set_hmap x y 255
x: x - 1
set_hmap x y min (60 + get_hmap x y) 255
y: y - 1
set_hmap x y min (60 + get_hmap x y) 255
]
]
/do [
t: now/precise/time
loop 8 [smooth_map] ;really slow loop (map erosion)
;loop 1 [smooth_map] ;really slow loop (map erosion)
probe t: now/time/precise - t
]
do [
map-img: make image! to-pair reduce [map_size_x map_size_y]
do make-map-image: does [
forall height_map [
poke map-img index? height_map 1.1.1 * first height_map
]
foreach [x y] peeks [set-pixel map-img x y 255.100.0]
height_map: head height_map
]
view center-face layout lay: [
size 400x400
backdrop
map-img effect [fit luma 10 contrast] 400x400
[quit]
rate :00:02 feel [engage: func [face act e] [
if act = 'time [
t: now/precise/time
smooth_map
t: now/precise/time - t
make-map-image face/image: map-img show face
timer/text: mold t show timer
]]
]
across label "smoth-secs:" font-color gray
timer: info 100x24 center font-color gray + 30.30.30
". o O o ."
at 240x10 title "Stars comming out.." gray
do []
]
]
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted