5

i have an object which is needed through out the game in every 10 seconds. shall i keep on deleting the object or keep on using the same object ? where does the object lies in so called "free time"?

as it's a mobile game, memory is a concern. so, just wanted to know which method would be fruitful.

"creating and deleting objects" ?

or

"reusing a object" ?

thanks

  • 1
    reusing an object or memory ? What do you mean of the two ? – Arunmu Feb 22 '12 at 13:39
  • 1
    it depends. it depends on your requirements, it depends on your choice of allocator, it depends on the object, it depends on the usage patterns. try to clarify your requirements and then **measure** – Cheers and hth. - Alf Feb 22 '12 at 13:39

4 Answers4

4

This depends very much on the nature of the object and the memory use of the rest of the program, but as a rule of thumb:

If you need the object throughout the program, then keep it in memory. If it's small, it won't matter. If it's big, then re-creating it every ten seconds will be a strain on the processor and the allocations might contribute to memory fragmentation as well.

If you choose to keep the object alive as I recommended, then while it's not used it will live in RAM and take up some space there (assuming your mobile platform does not have swap memory).

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
1

Reusing the object is cheaper, especially if creating and deleting operations are expensive (drawing, disk access, downloading), but having too many reusable objects in the cache might fill your memory.

Alexander
  • 8,117
  • 1
  • 35
  • 46
1

What does your profiler say?

It depends largely on the object, the compiler and the types of use you are making of it. The one time I benchmarked it (and std::string in the g++ library, being reinitialized each time through a loop), reconstructing the object each time in the loop was faster. On the other hand, most of the other standard containers retain their memory even when emptied; in such cases, if you define the container outside of the loop, it will (usually) arrive at its final size fairly quickly, after which there will be no other allocations.

And of course, you have to consider just how difficult it is to restore the object to a pristine state. It's almost impossible for objects derived from std::ios_base, for example; you almost always want to use a new std::ostringstream, rather than trying to reuse an existing one. Despite the cost.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • Doing memory tests in a simple loop is unfair. The reason is because it will just keep creating and destroying objects in the same order, thus the one block on memory can continually be reused (that is, the memory manager doesn't have any real work to do). – edA-qa mort-ora-y Feb 22 '12 at 19:11
  • @edA-qamort-ora-y Perhaps. But that was the issue at the time: was it faster to reuse an `std::string` declared above the loop, or to recreate one each time through the loop, assigning a new value to it. And I'm pretty sure that the results are an artifact of the g++ implementation of `std::string`: as with all measurements, there's absolutely no guarantee that you're end up with similar results with a different compiler and a different library. My point was only that you can't tell without measuring. – James Kanze Feb 23 '12 at 08:56
  • I'm just adding that it's hard to measure correctly, and simple isolated loops are usually not fair tests. – edA-qa mort-ora-y Feb 23 '12 at 09:30
  • @edA-qamort-ora-y It is hard to measure correctly. You have to more or less simulate actual code for the measurement to be relevant. In this case, the simple loop did simulate actual code: we were constructing strings in a loop, and inserting them into an `std::vector` member. (It's probably a common pattern.) – James Kanze Feb 23 '12 at 09:38
0

When an object is no longer used, the destructor is called in order to free the memory. But if you then create a new object of the same type, the constructor is called in order to alloc new memory. This certainly reduces the performance (in practice, however, it also depends on how big the object), so if you no longer need an object during program execution, you should reuse it by changing its content.

enzom83
  • 8,080
  • 10
  • 68
  • 114
  • "the constructor is called in order to alloc new memory" - not really. The constructor might allocate memory, it might not. – Steve Jessop Feb 22 '12 at 13:53
  • 1
    @SteveJessop: The constructor is typically used to allocate new memory. Moreover, the default constructor _calls the default constructors of all members that have them. If there is a member with some constructors, but without a default one, then it's a compile-time error_ (see [here](http://stackoverflow.com/questions/4837223/c-default-destructor)). – enzom83 Feb 22 '12 at 14:03
  • My point is that memory allocation is separate from construction. Constructors only allocate memory if they have a line in them (or a line in a base class or member constructor) that allocates memory, with `new` or `malloc` or whatever. – Steve Jessop Feb 22 '12 at 14:08
  • @SteveJessop: An user-defined constructor with an empty body and without arguments is equivalent to the compiler-generated default constructor. It's wrong to say that _this type_ of constructor takes no action. If I write `MyObject obj;` (without `new`), the compiler uses its default constructor. – enzom83 Feb 22 '12 at 14:16
  • Consider `struct MyObject { int i; MyObject() : i(0) {}};`. Then, if I write `MyObject obj;`, the constructor does not allocate any memory. Hence it is not "called in order to alloc new memory". – Steve Jessop Feb 22 '12 at 14:24
  • @enzom83 Most constructors that I've seen don't allocate memory. Memory allocation is only one reason to provide a constructor: std::complex, for example, has constructors, but doesn't allocate memory. For that matter, the default constructor of `std::vector` doesn't allocate memory in the implementations I'm familiar with. – James Kanze Feb 22 '12 at 14:27
  • The compiler-generated default constructor allocates new memory even if the members of the class are primitive data types: these members are not initialized with a specific value, but the compiler allocates new raw memory for these members. – enzom83 Feb 22 '12 at 14:35
  • In the `struct MyObject { int i; int j; MyObject() : i(0) {}};`, the constructor allocates new memory for two int (8 bytes) and initializes `i` to 0. If I write `MyObject obj; cout << sizeof(obj) << endl; cout << obj.i << endl;`, the `sizeof` operator print `8` (bytes) and `obj.i` is `0`. – enzom83 Feb 22 '12 at 14:43
  • Consider `struct MyObject { long *i; MyObject() {}};`: the `long` type is an integer of 8 byte, but `long*` is a _pointer to long_ (4 byte in 32 bit architecture). If I write `MyObject obj;` and `sizeof(obj)`, the `sizeof` operator returns `4` because the OS has allocated 4 byte for a pointer. The behavior is the same if we consider `struct MyObject { long *i; };` – enzom83 Feb 22 '12 at 14:50
  • @enzom83: no it doesn't. It is not the constructor that allocates memory for the object and its data members. – Steve Jessop Feb 22 '12 at 14:57
  • @SteveJessop: Well, what happens if I write `int main() { long *i; }`? – enzom83 Feb 22 '12 at 15:20
  • @enzom83: then you have an uninitialized automatic variable of type `long*`. The memory for it, `sizeof(long*)` bytes, is on the stack. Assuming the implementation uses a stack, but in fact they all do. – Steve Jessop Feb 22 '12 at 16:00
  • @SteveJessop: Yes, the memory for `long*` is uninitialized (without a specified value), but it is on the stack: since it is on the stack, the OS allocated `sizeof(long*)` bytes for it, so the memory is allocated but it is not initialized to a specified value. – enzom83 Feb 22 '12 at 17:15
  • @enzom83: and none of that was done by any constructor. – Steve Jessop Feb 22 '12 at 17:19