Page 2 of 2 FirstFirst 12
Results 11 to 20 of 25

Thread: CLASS vs. OBJECT and memory management

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Quote Originally Posted by phibermon View Post
    Yes - pre-allocate storage for data, pre-construct object instances and then just fetch them from the pools. You can grow as needed and construct double linked lists for quick insertion and deletion if required.
    That's just what the engines I know use (Build, Action Arcade Adventure Set). And this is the way I'll use in my engine.

    Like this:
    Code:
    TYPE
      TSpritePtr = ^TSPrite;
    
      TSprite = RECORD
        x, y: INTEGER;
        Bmp: ImageRef;
        NextSpr: TSpritePtr;
      END;
    
    VAR
       SpriteList: ARRAY OF TSprite; { Or a class containing the list, or a spezialized GENERIC or...}
       PlayerSpr: TSpritePtr;
       FirstEnemy: TSpritePtr;
       FirstBullet: TSpritePtr;
    Since the pointer itself is stored inside the list, there are very little CPU-cache collisions, so traverse the linked list should be quite fast.

    [edit]
    Fun fact: Actually this may be faster in the old times (i.e. 8086, 80286, 80386), when memory were divided in pages (do you remember the FAR and NEAR pointers?). If the whole list is in one single memory page, no page change is needed, and memory access may be faster specially if the related code is also in the same memory page. The AAAkit book talks about it too.

    Quote Originally Posted by turrican View Post
    Here is a little benchmark for Delphi I did.

    https://github.com/turric4n/Delphi-B...jectsVSRecords

    Records are more faster than Heap allocated Records (Pointer to Records) and much more faster than Objects.
    Thanks pal. It confirms the hypothesis "Objects/CLASSes are the slowest".

    [I must test it on FPC though, but I think it will be the same ]
    Last edited by Ñuño Martínez; 13-07-2017 at 08:09 AM.
    No signature provided yet.

  2. #2
    Quote Originally Posted by turrican View Post
    Here is a little benchmark for Delphi I did.

    https://github.com/turric4n/Delphi-B...jectsVSRecords

    Records are more faster than Heap allocated Records (Pointer to Records) and much more faster than Objects.
    It's tricky, I have similar tests and results depends on:
    1) How many records/objects exists
    2) Complexity of record/object (number or variables)
    The results will be completely different with:
    Code:
      TSpriteRec = record
        ID         : integer;
        x, y    : integer;
        Name    : String[80];
        angle     : double;
        alpha     : byte;
        components : array [0..9] of integer;
        p          : pointer;
      end;
    3) If features like sorting are needed

    In general array of pointers is fastest.
    Attached Files Attached Files
    Last edited by JC_; 15-07-2017 at 11:29 AM.

  3. #3
    Interesting.

    There are a lot of variables* involved. All these tests are useful but only the actual implementation will tell what is the fastest.
    _____________________________

    * Pun not intended
    No signature provided yet.

  4. #4
    Actually these shown test aren't so useful because they are poorly implemented. What is wrong with them?
    1. When testing WRITE performance of classes/objects the above tests measure both the creation time and first write to fields together. This of course does not provide real picture. Why? Because most of the measured time is actually spent in class creation. You see the main drawback of classes versus records is the fact that their creations takes longer time than record creation. Why is that.
      Because when creating class you don't just allocate memory for it like with records but you also execute some special initialization code that is required for classes.
      Now if you would split the test to measure class creation and field writing times separately you would see that writing to class fields isn't much slower than writing to record fields if it even is.
    2. When testing array of records tests only perform sequential access but not random access. Sequential access to array items is faster due the fact that arrays are always stored in memory as one single memory block and becouse stem memory also excels in perform in sequential memory access. You can observe this by using some memory diagnostic and measuring utils like MemTest.
    3. There is no test that would measure performance of adding or removing records during run-time. Here arrays lose quite a lot of performance because when removing of items you need to rearrange all other items in order to fill the gap. This can become quite slow when you have huge number of larger records as there is quite a bit of memory that needs to be moved. Also due the fact that arrays are always stored as one continuous block of memory it means that when you are extending the size of that array there needs to be sufficient free space after the existing array for resizing. If there isn't then the contents of the whole array needs to be copied to another location in memory where there is enough free space to hold the entire extended array in one continuous block of memory.
      When using lists of classes the above mentioned drawback are barely noticeable because their internal arrays only store references (pointers) to these classes so rearranging their items does not require so big memory movements. Also the data of these classes doesn't have to be stored in one continuous memory block.
    4. Another thing that can screw up tests results is doing random number generation inside the test method/loop itself. Why? Because time taken for generating single random number can vary quite a lot. Of course it most depends on what kind of random algorithm is being used. And it can also depend on whether your CPU perhaps have built-in support for random number generation. So I strongly recommend you generate all needed random numbers before testing and then read them from memory during the testing itself.
    5. And finally the problem of all of the above tests is that they are to short. What do I mean with that? Today's computers are made for multitasking which means that it is not necessary that when you are performing the test your application will be given all the available processing power of CPU core. Not to mention that since most modern CPU use automatic throttling to achieve better power saving it is not necessary that the CPU is working at max speed at the time when you are performing your tests. You can observe this by starting the above test multiple times where you will see varying results.
      So in order to get more accurate results it is best to make sure that the test are running for longer time or are repeated multiple times and then average time is calculated from the results.
    Last edited by SilverWarior; 17-07-2017 at 04:30 PM.

  5. #5
    Very good, very good.

Page 2 of 2 FirstFirst 12

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •