function implementation with stack vs heap allocation

H

Hicham Mouline

Hello,

I have a function f that is called a large number of times
my current implementation is

bool f( iterator begin, iterator end ... )
{
const size_t n =end - begin;
....
....
boost::scoped_array<some_type> a( new some_type[n] );
...
....
return true;
}

However I tested the same implementation with a on-stack allocation

bool f( iterator begin, iterator end ... )
{
const size_t n =end - begin;
....
....
const size_t maxN = 64;
if (n>64)
{
return false;
}
some_type a[maxN ]; // or maybe boost::array< some_type, maxN > a;
...
....
return true;
}

Given the size of my problem, I am mostly in implementation 2, but sometimes
it may be over 64 and therefore would like to use dynamic allocation.

How can I not duplicate the code ? I can't see it.

some_type* a;
if (n>64){
a = new ...
}
else{
a = ???
}


regards,

is this the kind of things STL allocators do? should I template this
function with an allocator?
 
S

SG

Hello,

I have a function f that is called a large number of times
my current implementation is

bool f(   iterator begin, iterator end ... )
{
const size_t n =end - begin;
 ....
 ....
 boost::scoped_array<some_type> a( new some_type[n] );
 ...
...
return true;
}

However I tested the same implementation with a on-stack allocation
[...]
Given the size of my problem, I am mostly in implementation 2, but sometimes
it may be over 64 and therefore would like to use dynamic allocation.

How can I not duplicate the code ? I can't see it.

The simple solution would be to separate allocation and the "real
work":

bool backend(iterator begin, iterator end, some_type* p, ..... )
{
// real work with p
}

bool f(iterator begin, iterator end, ..... )
{
const size_t n =end - begin;
if (n<=64) {
some_type arr[64];
return backend(begin,end,arr, ..... );
} else {
vector<some_type> vec (n);
return backend(begin,end,&vec[0], ..... );
}
}

Cheers!
SG
 
H

Hicham Mouline

Hello,

I have a function f that is called a large number of times
my current implementation is

bool f( iterator begin, iterator end ... )
{
const size_t n =end - begin;
....
....
boost::scoped_array<some_type> a( new some_type[n] );
...
...
return true;
}

However I tested the same implementation with a on-stack allocation
[...]
Given the size of my problem, I am mostly in implementation 2, but
sometimes
it may be over 64 and therefore would like to use dynamic allocation.

How can I not duplicate the code ? I can't see it.

The simple solution would be to separate allocation and the "real
work":

bool backend(iterator begin, iterator end, some_type* p, ..... )
{
// real work with p
}

bool f(iterator begin, iterator end, ..... )
{
const size_t n =end - begin;
if (n<=64) {
some_type arr[64];
return backend(begin,end,arr, ..... );
} else {
vector<some_type> vec (n);
return backend(begin,end,&vec[0], ..... );
}
}

Cheers!
SG
 
P

Pascal J. Bourguignon

Hicham Mouline said:
The simple solution would be to separate allocation and the "real
work":

bool backend(iterator begin, iterator end, some_type* p, ..... )
{
// real work with p
}

bool f(iterator begin, iterator end, ..... )
{
const size_t n =end - begin;
if (n<=64) {
some_type arr[64];
return backend(begin,end,arr, ..... );
} else {
vector<some_type> vec (n);
return backend(begin,end,&vec[0], ..... );
}
}

Cheers!
SG

Compile this function to assembler and see what it does. Short
answer: No, you won't lose anything. More, if you use a recent gcc,
you may get TCO so the return backend() is actually implemented with a
JMP instead of JSR/RET.
 
H

Hicham Mouline

Pascal J. Bourguignon said:
Hicham Mouline said:
The simple solution would be to separate allocation and the "real
work":

bool backend(iterator begin, iterator end, some_type* p, ..... )
{
// real work with p
}

bool f(iterator begin, iterator end, ..... )
{
const size_t n =end - begin;
if (n<=64) {
some_type arr[64];
return backend(begin,end,arr, ..... );
} else {
vector<some_type> vec (n);
return backend(begin,end,&vec[0], ..... );
}
}

Cheers!
SG
-------------------
I'd need to make backend inline...
otherwise I may lose the benefit gained from having the array on the
stack,
no?

Compile this function to assembler and see what it does. Short
answer: No, you won't lose anything. More, if you use a recent gcc,
you may get TCO so the return backend() is actually implemented with a
JMP instead of JSR/RET.

thanks....
I have this code pattern in many many f's. currently, it's just a dynamic
allocation with new....
If I replace all the occurences by the pattern above, I would need as many
backends as I have f's

isn't there a way to inline this in the code... to remove the need of
backend?

rds,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top