Mr Bones
Mr Bones

Reputation: 41

F# - Memory management

I am working on a basic engine to draw sprites on screen and I wanted to implement a frame - rate method that works as such:

  1. I have a background image stored in a 2D array (that never changes, if I need a different background I need to load a new image) that gets copied every time a new frame has to be made;
  2. all sprites are contained in a list contained in a list ordered in ascending z order. I am yet unsure wether to tap into multithreading or not as far as blitting is concerned. This list is mutable, so if a sprite is inserted , it's locked and sorted after insertion;
  3. the sprites are blitted on the 2D array mentioned in point 1 and after that it's displayed on screen.

The question I have is , if I want to bump the framerate up , will this cause an out of memory exception/error of some sort? Basically , will this eat all my memory before the language has enough time to free any? I know this is the case for some applications in Java that have to deal with many small instances being created, where the program can just crash (at least , it happened to me on a few instances). Is there a better way or is this good enough?

For clarification, my console / raster will never be wider or longer than a few hundred units, so say abot 100 * 80 is probably as big as it gets. Finally , my pixel class takes up 24 bytes (1 character , 1 background color , 1 foreground color).

Upvotes: 2

Views: 255

Answers (1)

Tomas Petricek
Tomas Petricek

Reputation: 243051

In general, the garbage collector should be good enough to collect unused objects on the fly. It is hard to give any specific comment about how efficient this will be for your purposes - I think you just have to write a prototype to test the performance and see if that is good enough for you.

One important thing is that F# (and .NET) support "value types" (structs) which are not going to be allocated as individual objects on the heap. When you create a (2D) array of value types, it will be just a single continuous block of memory (rather than 1+80,000 separate object instances).

To define a value type, you can use the Struct attribute:

open System.Drawing

[<Struct>]
type Pixel(c:char, bg:Color, fg:Color) = 
  member x.Char = c
  member x.Background = bg
  member x.Foreground = fg

let a2d = 
  Array2D.init 100 80 (fun i j -> 
    Pixel('a', Color.Red, Color.Black))

Upvotes: 3

Related Questions