ID:1100953
 
Code:
var/SaveInt = 300 // supposed to be 18000 for 30 minutes
var/mapsave/MapSave
proc
save_timer()
var/count = SaveInt
for()
if(count <= 0)
spawn(0) MapSave.Save()
count = SaveInt
count -= 10
sleep(10)

world
New()
..()
MapSave = new /mapsave
//spawn() save_timer()

mapsave

proc
Save()
world << "Saving the world in 10 seconds."
sleep(100)
Save_T()
Save_O()
// other types of saving

Save_T()
var/count = 0
var/Filename = "Data/Maps/Mapsave.sav"
if(fexists(Filename)) fdel(Filename)
var/savefile/S = new(Filename)
var/oldcd = S.cd
for(var/z=1,z<=world.maxz,z++)
sleep(1)
S.cd = "[z]"
for(var/x=1,x<=world.maxx,x++)
S.cd = "[x]"
for(var/y=1,y<=world.maxy,y++)
S.cd = "[y]"
var/turf/T = locate(x,y,z)
S["type"] << T.type
//S["icon"] << T.icon
//S["icon_state"] << T.icon_state
//S["Flyable"] << T.Flyable
count++
S.cd = ".."
S.cd = ".."

S.cd = oldcd
world << "Turfs Saved ([count])"

Save_O()
var/count = 0
var/Filename = "Data/Maps/Objects.sav"
if(fexists(Filename)) fdel(Filename)
var/savefile/S = new(Filename)
var/oldcd = S.cd
for(var/z=1, z<=world.maxz, z++)
sleep(1)
S.cd = "[z]"
for(var/x=1, x<=world.maxx, x++)
S.cd = "[x]"
for(var/y=1, y<=world.maxy, y++)
S.cd = "[y]"
var/turf/T = locate(x,y,z)
var/list/os = list()
os += T.contents
for(var/a in os)
if(istype(a, /mob))
os -= a
S["contents"] << os
count += os.len
S.cd = ".."
S.cd = ".."
S.cd = oldcd
world << "Objects Saved ([count])"


Problem description:
Hey everyone =)
Been working on a mapsaving system, and I finally figured out how to save them. Granted, this saves every tile regardless of whether its new or not (I intend to fix that along the line). It bothers me because even though my PC is only a single core 3.06 Ghz, with 1GB of RAM, This takes between 9-18 seconds to save all the tiles, which is 80,000. I commented out a few of the variables I was saving with it to test if it was slowing it down, and yes it was. With those variables included it ranges from about 40-60 seconds.

The objects amount to about 7k, and that takes about 20 seconds to save.

So.. does anyone have any ideas on how to speed up this process? My goal is to have seamless saving, I'm hoping there are some things I'm missing here which are slowing the saving down.

I'm pretty sure there's a limit on savefiles.
Kitsueki wrote:
> var/SaveInt = 300 // supposed to be 18000 for 30 minutes
> var/mapsave/MapSave
> proc
> save_timer()
> var/count = SaveInt
> for()
> if(count <= 0)
> spawn(0) MapSave.Save()
> count = SaveInt
> count -= 10
> sleep(10)
>
> world
> New()
> ..()
> MapSave = new /mapsave
> //spawn() save_timer()
>
> mapsave
>
> proc
> Save()
> world << "Saving the world in 10 seconds."
> sleep(100)
> Save_T()
> Save_O()
> // other types of saving
>
> Save_T()
> var/count = 0
> var/Filename = "Data/Maps/Mapsave.sav"
> if(fexists(Filename)) fdel(Filename)
> var/savefile/S = new(Filename)
> var/oldcd = S.cd
> for(var/z=1,z<=world.maxz,z++)
> sleep(1)
> S.cd = "[z]"
> for(var/x=1,x<=world.maxx,x++)
> S.cd = "[x]"
> for(var/y=1,y<=world.maxy,y++)
> S.cd = "[y]"
> var/turf/T = locate(x,y,z)
> S["type"] << T.type
> //S["icon"] << T.icon
> //S["icon_state"] << T.icon_state
> //S["Flyable"] << T.Flyable
> count++
> S.cd = ".."
> S.cd = ".."
>
> S.cd = oldcd
> world << "Turfs Saved ([count])"
>
> Save_O()
> var/count = 0
> var/Filename = "Data/Maps/Objects.sav"
> if(fexists(Filename)) fdel(Filename)
> var/savefile/S = new(Filename)
> var/oldcd = S.cd
> for(var/z=1, z<=world.maxz, z++)
> sleep(1)
> S.cd = "[z]"
> for(var/x=1, x<=world.maxx, x++)
> S.cd = "[x]"
> for(var/y=1, y<=world.maxy, y++)
> S.cd = "[y]"
> var/turf/T = locate(x,y,z)
> var/list/os = new()
> os += T.contents
> for(var/a in os)
> if(ismob(a))
> os -= a
> S["contents"] << os
> count += os.len
> S.cd = ".."
> S.cd = ".."
> S.cd = oldcd
> world << "Objects Saved ([count])"
>


I replaced istype(a,/mob) with ismob(a) and redefined the os.

In edition, I have a proc that cycles through a 250x250 map(only searches 3 z-levels) for available, non-dense non-safe turfs. You could try and read through it, have fun with that.

proc
Check_Locs(){ set background = 1; var/w=1; var/q=1; var/e=1; while(e<4){ var/turf/t=locate(w,q,e); if(t.density||!isturf(t)){ goto noAdd }; for(var/atom/a in view(0,t)){ if(a.density||istype(a,/area/house/)){ goto noAdd; break }}; if(e==1){ available_locs1.Add(t) }; else{ if(e==2){ available_locs2.Add(t) }; else{ if(e==3){ available_locs3.Add(t) }}}; noAdd; w++; if(w>world.maxx){ w=1; q++; }; if(q>world.maxy){ q=1; e++; }}}

Profile results (total time)
Proc Name | Self CPU | Total CPU | Real Time | Calls
--------------------------------- --------- --------- --------- ---------
/proc/Check_Locs | 0.553 | 0.553 | 0.553 | 1
Alright, those are a few optimizations, and a bit of useful knowledge for me to boot, thank you sir.

These however do little for the codes running time... I'm thinking this might need a lot of restructuring.
In fact..

What if I created lists for each type I'm saving, then sorted out all the types I'm saving in that one call. After the maps have been searched through, I activate a proc which saves each of the lists into a respective savefile.

You have a good concern on the savefile limit too, nnaaaahh.
I think I'll add in a bit that starts a new savefile after so many tiles.
In response to Kitsueki
The saving is probably what takes the most resources. You're writing so much into savefiles.

As for the savefile size cap; You could save each turf in its own savefile, and just keep it under a folder named 'turfs' or something of the like. Then use for(var/savefile/s in flist("/turfs/")). This would probably never reach the savefile size limit, as I doubt anything would take up that much space by itself.

Personally:
for(var/savefile/s in flist("/turfs/"))//for each savefile for each turf
[load the turf]//load whatever you need
del s//then delete the savefile to be re-created whenever you next save.
//this also means checking if the savefile exists and then deleting it wouldn't be required, if you're only saving/loading it once.


Not sure if having one big savefile you save everything in is less costly than making a bunch of smaller files, not sure why it would be any different. It appears writing references to a image/atom in a savefile takes up the most resources. Making the actual savefile itself, I'm unsure of.
Yeah, that was my theory. I'll just limit the savefile to.. say.. 25k tiles each.

Trying out the way I mentioned now, once I get done coding it I'll see if it helps any.