Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Newcomers AppGameKit Corner / Do initialized, unused variables eat up lots of memory?

Author
Message
Greenwich
4
Years of Service
User Offline
Joined: 10th Dec 2014
Location:
Posted: 21st Jan 2015 05:32
I have a poor understanding of memory load and an impatience for games that routinely crash, and figure maybe I can get help for at least one of those problems.

I have a type Coordinates with integer variables .X, .Y, .UU, .UV, .VU, .VV, .H, .K, .T which I've been using to keep track of moving sprites' intended destinations and configurations (for items that don't use physics, like alert boxes). It's convenient because I can assign a single variable to a collection of sprites and particle emitters that 'belong together' as part of one object.

Unrelatedly, I've also been trying to design a way to track mouse movement over time, to create a mousetrail on the screen. I'm planning to eventually create a program that evaluates how well a user traces around a circle with their mouse. For that, I've been using an array of type Coordinates[3600] to store the mouse pointer location each frame, for a maximum of sixty seconds. But in this case I only really need .X, .Y information per frame, which means I'm creating 25,200 integer variables that I'll never use.

Obviously I'm aware that I *can* create separate types, and will for this particular case, but this got me wondering just how careful and judicious I ought to be.

Will having AppGameKit create hundreds of thousands of empty initialized unused integer variables cause a significant memory/workload concern, on typical low-end mobile devices? Or do variables take up so little space individually that this is a drop in the bucket? Or does AppGameKit kind of ignore those variables until used?

I don't even know how to test the potential for problems, or the threshold for concern, since presumably any memory error would only occur when there's already a ton of sprites on screen and other stuff happening. All by itself, creating the array and filling its X and Y coordinates doesn't seem to cause any problems or slowdown.

Thanks in advance

It's mean time. *averages*
baxslash
Valued Member
Bronze Codemaster
12
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 21st Jan 2015 09:00
Memory is always used when a variable is initialised. Not much but if you're talking about thousands it might be worth thinking whether you're doing it the right way. I have found that no matter what I am doing if I try to do it as economically as possible at runtime it always helps. I would try to store these variables in an array and only put valid values in. Arrays can be re-sized extremely easily.

If you are using V2 there are even simpler ways to use arrays than there were in V1 with the addition of commands such as 'insert' and 'remove'.

So in short, yes memory is being used and may impact performance in this case. Best to try to be lean with what resources you are using.


Using AppGameKit V2 Tier 1
paulrobson
4
Years of Service
User Offline
Joined: 22nd Nov 2014
Location: Norfolk, England
Posted: 21st Jan 2015 14:29
It's a good thing to be memory efficient, even if it doesn't impact too much. I've seen (and had to fix !) so much code where the developer clearly has not given one seconds thought to how much memory was being used, how long a method took etc etc etc. I learnt on a machine with 256 bytes of RAM which does teach you to think about these things. Bad habits spread easily.

If you are really worried about it there are various things you can do.

1) Define a simpler sub type with just X and Y.
2) Store X and Y as a single integer but pack the two values into on 32 bit integer. X * 10000 + Y and use modulus and division to get it back.
3) Don't collect data at 60 fps. If you collect it at 20 fps it will probably get much the same result ; the human eye can see differences upto about 20fps (though it can detect 'overall quality' in higher fps).
4) Calculate the error as you go. You are tracing round a circle, right ? So rather than save all the coordinates and then calculate how well this was done, computer the error as you go along.

Objective answer:

You are using a mouse to do this. Therefore it is likely to be running on a PC or a Macintosh - it is things like tablets and phones where both CPU time, Graphics and RAM resources are stretched. In those computers 3600 x 8 x 4 bit integers is nothing, it doesn't matter.

What I would avoid is overusing insert and remove. It is often better to allocate the whole thing at the start. The reason behind this is that when you extend an array, you may have to move memory to make the array longer, or reallocate it somehow (how depends on the AppGameKit runtime). BASICs have generally had static array sizes, but strings have always been dynamic - as you changed the value of the string this would be done on some sort of heap which at some point would be garbage collected.

This is the reason that languages like Java and C# often have something called a 'StringBuilder' object or similar - it's something that allows you to work with a continually increasing string without it impacting memory management too much. So instead of someString = someString + someNewStuff endlessly, you have someStringBuffer.append(someNewStuff) so it can chunk the memory management.
Kevin Picone
16
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Australia
Posted: 22nd Jan 2015 01:45
Greenwich,

If you look at our most commonly used data types in BASIC, we've go 32bit Floats, 32bit Integers which are both 4bytes per value, strings are of variable length, generally padded to some boundary to avoid constant resizing the buffer, so a 4 byte string of "ABCD" say, might actually be consuming 32->64 or possibly 128->256 bytes initially. They do this so can be resized up without requiring constant allocation (performance death). When a potential string concentration breaks the string buffer size, the engine would allocate another oversized buffer and the process repeats.

There's a number ways of building Arrays, but generally there's a header structure with the raw data. If your array contained say 100 unique integer cells , then it's at least 100*4 (4 bytes per integer) + whatever the header size is. So just say the header is 64 bytes for example. Our 100 unique cell integer array is only eating 464 bytes of memory.

Types are just packed together data. So a type with 10 integer fields, would be (10 * 4) 40 bytes. SO a typed array of 200 would cost 200*40 + 64 (assumed HeaderSize in bytes). So 8064 bytes, give or take. That's assuming a packed array, some implementations use pointers to type data. Which would add another 4 bytes per cell.


Quote: "25,200 integer variables"


That's about 100,800 bytes, which is nothing to really worry about.

BatVink
Moderator
16
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 22nd Jan 2015 11:45
Quote: " I've been using an array of type Coordinates[3600] to store the mouse pointer location each frame, for a maximum of sixty seconds"


Are you bothered about the time element of this, or just the position? I imagine that for some timeframes, the pointer never moves.

I created an app for signing your name, which is essentially the same functionality. I recorded a new point every time it was 5 pixels from the previous one, then drew a line between the two. Visually, I didn't lose any fidelity, it looked just fine. In fact it looks better than recording every pixel, which can look like a 2-year-olds scrawl. Datawise it saved me a lot of space (I imagine you you won't travel 300 pixels every second continuously for 60 seconds)


If you continue with your current approach (you'll definitely have to if time is an essential part of the logic) I would also consider whether you need data every 1/60th of a second. As mentioned earlier, it can improve the look by interpolating the movement. For human interaction 1/60th second is very small indeed.

Quidquid latine dictum sit, altum sonatur
Greenwich
4
Years of Service
User Offline
Joined: 10th Dec 2014
Location:
Posted: 25th Jan 2015 04:23
All very good responses, I appreciate them.

Quote: "Best to try to be lean with what resources you are using.
--baxslash"


Yes, this makes sense. The trouble I anticipate is that being maximally lean might make object-oriented programming (which I am new to) more difficult. (Really it just means I need to think about what I'm doing more carefully.

Quote: "What I would avoid is overusing insert and remove. It is often better to allocate the whole thing at the start.
--paulrobson"


That's something I had considered and was uncertain about -- whether the overhead of declaring and un-declaring variables would exceed the overhead of declaring lots of variables that ended up unused.

You made good suggestions. In this particular case I've already implemented suggestions (1) and (3). I split the extra variables into their own type, Destination, leaving Coordinates as X and Y only, and I reduced coordinate-collection to four times per second.

Suggestion (2) is clever, but I hope I won't ever have to go to quite *that* length. The idea (4) of tracking the error as I go is a good one, and may be necessary, I'll have to see.

Quote: "So 8064 bytes, give or take. That's assuming a packed array, some implementations use pointers to type data. Which would add another 4 bytes per cell. ... about 100,800 bytes, which is nothing to really worry about.
--Kevin Picone"


Thanks, I'll make a note of the size definitions and computations. How and when allocation happens is something I plan to learn more about (in part because I don't want to end up being one of those careless coders paulrobson was talking about).

Quote: "Are you bothered about the time element of this, or just the position?
--Batvink"


Goooooooood question. It's not something I ever thought to consider.

It is, as I envision it, a timed objective: stay between the inner circle bound and the outer circle bound, with the two boundary circles coming closer together as time passes. (I should mention I am having a terribly difficult time attempting to implement this.)

Regardless, I'm not sure if that means I need to store the traced path's coordinates by time. And even if I do, maybe I could just store timer() alongside X and Y.

In addition to this animation, I had originally intended to have the traced path's width depend upon the speed of the pointer motion, so that if someone paused or slowed their movement it would thicken. But that might not be feasible anyway.

Quote: "I recorded a new point every time it was 5 pixels from the previous one, then drew a line between the two. Visually, I didn't lose any fidelity, it looked just fine. In fact it looks better than recording every pixel, which can look like a 2-year-olds scrawl."


This is ingenious. I was working on "smoothing out" the minor kinks and such from the path, but this would pre-emptively smooth the path.

---

Thanks everybody!

It's mean time. *averages*
Greenwich
4
Years of Service
User Offline
Joined: 10th Dec 2014
Location:
Posted: 25th Jan 2015 04:28
Whoever changes the post titles to include [Answered], please feel free to mark this one. Thanks!

It's mean time. *averages*

Login to post a reply

Server time is: 2019-08-25 23:36:41
Your offset time is: 2019-08-25 23:36:41