473,385 Members | 1,772 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Price of Creating Local Objects

I have a method that uses a fairly large object. The choice is
between having a local object in the method or a static member object
that the method uses.

------CHOICE 1---------

int MyClass::myMethod(int param) {
MyBigObject o();
//initialize o based on param
//do calculations with o
return calclulatedValue;
}

------CHOICE 2---------

int MyClass::myMethod(int param) {
const MyBigObject& o = m_staticMemberHoldingAMyBigObject;
//re-initialzie o based on param
// rest is same as above
}

How much extra work is involved in the creation of the local object
with each call of myMethod()? More precisely, what actually happens?
Is new memory allocated for the object each time? Is the memory
allocated on the stack? On a temporary stack which exists during the
method call? I'm trying to understand what goes on under the hood as
well as find an answer to the practical problem.

Is it also true that choice 1 would be thread safe, while choice 2
would not?

Thanks for any help,
cpp
Jul 22 '05 #1
9 2495
"cppaddict" <he***@hello.com> wrote in message
news:bv********************************@4ax.com...
I have a method that uses a fairly large object. The choice is
between having a local object in the method or a static member object
that the method uses.
How large is large? 50 bytes? 1 kilobyte? 1 megabyte?
------CHOICE 1---------

int MyClass::myMethod(int param) {
MyBigObject o();
Declares a method named "o" that takes no arguments and returns a
MyBigObject. You probably meant

MyBigObject o;
//initialize o based on param
//do calculations with o
return calclulatedValue;
}

------CHOICE 2---------

int MyClass::myMethod(int param) {
const MyBigObject& o = m_staticMemberHoldingAMyBigObject;
//re-initialzie o based on param
// rest is same as above
}

How much extra work is involved in the creation of the local object
with each call of myMethod()? More precisely, what actually happens?
Is new memory allocated for the object each time? Is the memory
allocated on the stack? On a temporary stack which exists during the
method call? I'm trying to understand what goes on under the hood as
well as find an answer to the practical problem.
In general, variables that are declared locally within a function are
allocated quickly. If the object were monstrous, then I could see how one
might want to avoid declaring it as a local variable to a function, but that
generally deals with issues of <implementation>stack space</implementation>.
I wouldn't worry too much about what actually happens. Instead, concentrate
on questions like "How fast is it?" It's easy to take measurements and
determine answers for questions about efficiency. If you're concerned that
the program might fail because the object is not a static member of a class,
then, by all means, consult the implementation.
Is it also true that choice 1 would be thread safe, while choice 2
would not?


Threads are not a part of standard C++, but, for every implementation that I
could imagine, the first is thread-safe and the second is not, unless you
provide a mutex.

--
David Hilsee
Jul 22 '05 #2
>How large is large? 50 bytes? 1 kilobyte? 1 megabyte?

About 1 kilobyte.
Declares a method named "o" that takes no arguments and returns a
MyBigObject. You probably meant

MyBigObject o;
Woops. Yes, that is what I meant.
In general, variables that are declared locally within a function are
allocated quickly. If the object were monstrous, then I could see how one
might want to avoid declaring it as a local variable to a function, but that
generally deals with issues of <implementation>stack space</implementation>.
I wouldn't worry too much about what actually happens. Instead, concentrate
on questions like "How fast is it?"
I was hoping to get a feel for "How fast is it?" by understanding what
goes on behind the scenes. Of course, I could just time it and see,
but then I would have no insight. I'm actually pretty sure that speed
would not be an issue, but only because I vaguely know that vaguely
similar code has executed quickly.
If you're concerned that
the program might fail because the object is not a static member of a class,
then, by all means, consult the implementation.
That is not a concern. Is there any reason you think it should be?
Threads are not a part of standard C++, but, for every implementation that I
could imagine, the first is thread-safe and the second is not, unless you
provide a mutex.


Thank for your help,
cpp

Jul 22 '05 #3
"cppaddict" <he***@hello.com> wrote in message
news:tt********************************@4ax.com...
How large is large? 50 bytes? 1 kilobyte? 1 megabyte?


About 1 kilobyte.


That's probably nothing to be concerned about. I've dealt with C programs
that, in nearly every function, allocated around 500 bytes just for a
temporary sprintf() buffer.
In general, variables that are declared locally within a function are
allocated quickly. If the object were monstrous, then I could see how onemight want to avoid declaring it as a local variable to a function, but thatgenerally deals with issues of <implementation>stack space</implementation>.I wouldn't worry too much about what actually happens. Instead, concentrateon questions like "How fast is it?"


I was hoping to get a feel for "How fast is it?" by understanding what
goes on behind the scenes. Of course, I could just time it and see,
but then I would have no insight. I'm actually pretty sure that speed
would not be an issue, but only because I vaguely know that vaguely
similar code has executed quickly.


If you really want to know exactly what is going on behind the scenes, you
should examine the implementation. If you're more interested in how fast it
executes, then measurements will be more helpful. In general, it is
relatively quick, because local variables usually result in some fiddling
with the stack, which is usually a cheap operation. Of course, any comments
mentioning to a "stack" are referring to a possibly common implementation.
If you're concerned that
the program might fail because the object is not a static member of a class,then, by all means, consult the implementation.


That is not a concern. Is there any reason you think it should be?


Well, as I mentioned before, there can be a "stack space" exhaustion issue,
but that's not usually a problem for most applications. It's more of a
problem for applications that use highly recursive algorithms.

--
David Hilsee
Jul 22 '05 #4
"cppaddict" <he***@hello.com> wrote in message
news:bv********************************@4ax.com...
I have a method that uses a fairly large object. The choice is
between having a local object in the method or a static member object
that the method uses.

------CHOICE 1---------

int MyClass::myMethod(int param) {
MyBigObject o();
//initialize o based on param
//do calculations with o
return calclulatedValue;
}

------CHOICE 2---------

int MyClass::myMethod(int param) {
const MyBigObject& o = m_staticMemberHoldingAMyBigObject;
//re-initialzie o based on param
// rest is same as above
}

How much extra work is involved in the creation of the local object
with each call of myMethod()? More precisely, what actually happens?
Is new memory allocated for the object each time? Is the memory
allocated on the stack? On a temporary stack which exists during the
method call? I'm trying to understand what goes on under the hood as
well as find an answer to the practical problem.

Is it also true that choice 1 would be thread safe, while choice 2
would not?

Thanks for any help,
cpp


From what you have described, its impossible to advise you
on what effort is involved. When you declare an object in
a member function as in case 1, memory for the object is
provided by the stack, although internally the object may also
allocate memory using the free-store (new). Generally, allocating
with the free store is more expensive in run-time than the stack approach,
and memory obtained from the free-store should also be "freed" which is
another operation which
is not required when you allocate objects on the stack. Object allocation
and
deallocation on the stack is very fast since its just a matter of keeping
track
of the high and low addresses which bound an object. What's more, as
objects
as destroyed automatically as they go out of scope, the memory the objects
use is
recycled. However, the stack is of course of finite size, so if you are
going to have deeply nested calls which allocate large objects on the stack
, you mightwant to reconsider how you allocate your objects.

Of the architectures I know, there is not a "temporary" stack, there's the
one stack, it just grows to handle the data used in a function call and
shrinks back when the call returns, its just one contiguous area of memory.

There is not enough information to tell if choice 1 or choice 2 is thread
safe.
You only have to worry about thread safety when you are sharing a single
resource
between multiple threads and the threads can potentially change the state of
that resource.
If the object in choice1 is actually accessing such a shared resource, then
its not thread safe,
even though only one thread can access the object.
Choice 2 is actually a reasonable approach in a multi-threaded enviroment
when you add synchonrization objects (locks) to serialize access to the
static object.

dave
Jul 22 '05 #5
>Generally, allocating
with the free store is more expensive in run-time than the stack approach,
and memory obtained from the free-store should also be "freed" which is
another operation which
is not required when you allocate objects on the stack. Object allocation
and
deallocation on the stack is very fast since its just a matter of keeping
track
of the high and low addresses which bound an object.


Dave,

Thanks for your thoughts. I did know that using the heap is more
expensive than the using the stack, but could you explain why that is?

What are all the extra things that need to be done?

Also, when you say that allocating on the stack is just a matter of
tracking the high and low addresses, that does not include the expense
of object initialization, does it? That is, it doesn't include the
time it takes to execute the code in the objects constructor? Or does
it?

Thanks again,
cpp
Jul 22 '05 #6
On Fri, 13 Aug 2004 06:32:28 +0000, cppaddict wrote:
Generally, allocating
with the free store is more expensive in run-time than the stack approach,
and memory obtained from the free-store should also be "freed" which is
another operation which
is not required when you allocate objects on the stack. Object allocation
and
deallocation on the stack is very fast since its just a matter of keeping
track
of the high and low addresses which bound an object.
Dave,

Thanks for your thoughts. I did know that using the heap is more
expensive than the using the stack, but could you explain why that is?


All this is implementation specific of course but I think very common.
Every sizable object needs some memory to live on. The memory for
automatic objects is allocated as cheaply as adjusting a register (stack
pointer).

Modifying the stack pointer reduces/increases available stack
space. Objects live on the stack one after the other.
What are all the extra things that need to be done?
When memory is explicitly requested for an object by operator new, then
the memory allocator must find a suitable place for an object of that
particular size.

Pool allocators keep available chunks of memory according to their
sizes. For example, objects having sizes 32 to 64 bytes could live in
the same memory block. This could be to ensure that small objects are
kept together so that large memory chunks are available for larger
objects.

When the object is deleted later on, the memory is returned to the
appropriate pool.

All of this takes CPU time
Also, when you say that allocating on the stack is just a matter of
tracking the high and low addresses, that does not include the expense
of object initialization, does it? That is, it doesn't include the
time it takes to execute the code in the objects constructor?


We are not talking about object construction on that memory, because the
cost of construction is the same for automatic vs. dynamic objects.

Ali

Jul 22 '05 #7


cppaddict wrote:

Also, when you say that allocating on the stack is just a matter of
tracking the high and low addresses, that does not include the expense
of object initialization, does it? That is, it doesn't include the
time it takes to execute the code in the objects constructor? Or does
it?


First the space has to be found in free store. This might be require
requesting space from the OS it could also involve a search of the free
blocks (though most allocators keep a sorted list of block on size).

Deletion will involve return the block to free store, coallesced it with
surounding free blocks etc, updating the sorted list of free blocks.

You'll really need to check on the implementation you are using. But
I'll tell you that on a windows system new/delete is very expensive.

Jul 22 '05 #8
cppaddict <he***@hello.com> wrote in message news:<bv********************************@4ax.com>. ..
I have a method that uses a fairly large object. The choice is
between having a local object in the method or a static member object
that the method uses.
The factor to consider is not really the size of the object, but the
amount of work required to initialize the object. A large object
that's left mostly uninitialized until use might be much cheaper to
create than a tiny object that's initialized by retrieving data from
(say) a database over the network.

[ ... ]
How much extra work is involved in the creation of the local object
with each call of myMethod()?
That depends on what the object's ctor does.
More precisely, what actually happens?
Is new memory allocated for the object each time? Is the memory
allocated on the stack?
With a typical machine, space for local objects is allocated on a
stack. Allocating stack space is roughly constant time regardless of
size (barring things like paging getting involved).
Is it also true that choice 1 would be thread safe, while choice 2
would not?


Generally speaking, yes.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 22 '05 #9

"cppaddict" <he***@hello.com> wrote in message
news:sq********************************@4ax.com...
Generally, allocating
with the free store is more expensive in run-time than the stack approach,and memory obtained from the free-store should also be "freed" which is
another operation which
is not required when you allocate objects on the stack. Object allocationand
deallocation on the stack is very fast since its just a matter of keeping
track
of the high and low addresses which bound an object.


Dave,

Thanks for your thoughts. I did know that using the heap is more
expensive than the using the stack, but could you explain why that is?

What are all the extra things that need to be done?

Also, when you say that allocating on the stack is just a matter of
tracking the high and low addresses, that does not include the expense
of object initialization, does it? That is, it doesn't include the
time it takes to execute the code in the objects constructor? Or does
it?

Thanks again,
cpp


Each implementation of the freestore/heap has its own optimizations and
(proprietary) implementation details, but the general approach is as
follows:

The free store manages memory for allocations by first obtaining
memory from the operating system in large contiguous chunks. Individual
requests for memory are made out of these chunks. Internally the free-store
manager maintains knowledge of what memory has been allocated and what
is available for requests. When you make a request for a memory allocation
through new (or malloc) the manager will check to see if it has a suitable
piece
of memory on hand, and if so, will provide you with an allocation. If not,
then
it will make calls to the operation system ("sbreak") to obtain more memory
if possible and
then try to make your allocation. Usually, the piece of memory you obtain
from
the heap is slightly bigger than you requested, typically, the free bytes
before the
actual pointer value you get are dedicated to the manager's book keeping so
that
the memory can be re-absorbed into the free-store when you deallocate/delete
it.
( there are also issues of alignment, memory is usually allocated on 8 byte
(typically)
boundaries so that any datatype (ie double) can be correctly aligned, also
allocations
are usually rounded up to 4 or 8 byte multiples for convenience).

When you deallocate (delete) a piece of memory, the memory is "reabsorbed"
into the
system. Some systems will try to coallesc pieces of deallocated memory
together to form the largest
contigious range as part of a strategy to avoid "fragmentation" of the
system's memory.

Some systems provide a useful debugging feature where memory is "painted" in
certain patterns
to indicate the memory has been allocated but not initialized, or
deallocated.
A number of implementation efficiencies can be incoporated into any
particular system which greatly improves the run-time efficiency and memory
efficiency. Still, there are usually a number of function
calls made to allocate and deallocate a block, even under the best
circumstances when memory
is on-hand for the manager to dole out to the caller. I don't have actual
numbers to hang my
hat on, but the stack allocation is certainly a lot faster than the
freestore/heap allocation. .
Jul 22 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: ajit goel | last post by:
Hi; I have a question which respect to initialising and creating objects in loops.Here are the 2 scenarios: 1. ###############################################################################...
4
by: Robbie Hatley | last post by:
I've been playing with "auto_ptr" and the "Resource Acquisition Is Initialization" concept. On page 199 of Lippman's book "Effective C++" he says "All active local class objects of a function are...
3
by: Gigi.com | last post by:
Hi All. I need some help trying to pull prices from a price matrix. Here's an example: >>>> 1000 1500 2000 2500 ----------------------------------------- 1000 ¦ 10.20 ...
4
by: Jason M | last post by:
Hi, Im very new to c#, so forgive me if this is a really stupid question. Im trying to create a form for entering purchase requests. For each line item I have a quantity, a description unit cost...
9
by: Stefan Turalski \(stic\) | last post by:
Hi, I done sth like this: for(int i=0; i<10; i++) {...} and after this local declaration of i variable I try to inicialize int i=0;
9
by: Patrick.O.Ige | last post by:
I have a code below and its a PIE & BAR CHART. The values now are all static but I want to be able to pull the values from a database. Can you guys give me some ideas to do this? Thanks ...
23
by: Timothy Madden | last post by:
Hello all. I program C++ since a lot of time now and I still don't know this simple thing: what's the problem with local functions so they are not part of C++ ? There surely are many people...
1
by: joe_doufu | last post by:
I'm creating a page with multiple "widgets", each with its own XMLHttpRequest object, so the user can play with the widgets in parallel. The widgets are enclosed in divs with class "widget" and a...
19
by: =?Utf-8?B?WWFua2VlIEltcGVyaWFsaXN0IERvZw==?= | last post by:
I'm doing my c# more and more like i used to code c++, meaning i'm casting more often than creating an instance of objects. like : protected void gvOrderDetailsRowDataBound(object sender,...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.