-
Dynamic Memory Allocation Which is best?
I am using following ways to Allocate & Deallocate memory dynamically
1. Using malloc() and free ()
2. Using calloc() and free()
3 using new and delete operator
4 using stl <vector>
Ok all are different styles. But i looking the better performence.During the use of stl allocation application is very slow. Multiple times calling of new and delete will reduce the application efficiency.
On the shadow of these points how i choose a way which give optimum use of CPU. Which is the best on first 3 ways ?
-
Re: Dynamic Memory Allocation Which is best?
I feel No. 2 is best way!
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by getzephyr
I feel No. 2 is best way!
The exact opposite is true. No. 2 is not to be used in a C++ program, unless you can justify in using it. It should be the last choice.
How are you going to use No. 2 if you need to create a dynamic array of non-POD types?
Regards,
Paul McKenzie
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Dave1024
Ok all are different styles. But i looking the better performence.During the use of stl allocation application is very slow. Multiple times calling of new and delete will reduce the application efficiency.
I can come up with many examples where using new[] and delete[] repeatedly is many times slower than just using a vector and vector.resize().
If you show us what you're doing with vector, I'm sure someone will make recommendations as to what you may be doing that's inefficient. Just saying that something is slow doesn't make it slow -- it could be the programmer that isn't using it efficiently (and correctly) that would make it slow.
Quote:
On the shadow of these points
You need to prove these points to us, before anyone can answer you.
But as I mentioned to the other poster, how are you going to use low-level 'C' functions to dynamically create an array of non-POD types. For example, you can't use malloc() or calloc() here:
Code:
#include <string>
int main()
{
std::string *pString = (std::string*) malloc( 10 * sizeof(std::string));
//...
}
This code is ill-formed and leads to undefined behaviour. The reason is that you have not created 10 strings, i.e. the constructor of the string objects was never called to actually create the objects. Therefore using malloc() or calloc() is not an option. So your original question is invalid if your objects have user-defined constructors.
The only exception to this is if you're going to use placement-new and you need to initially call malloc() to allocate the memory. But you never mentioned placement-new, so I left it out of the discussion.
The bottom line is that you write the program correctly first. If and only if there are bottlenecks do you use dynamically allocated memory. Therefore the first choice would be vector to get the program to work, then making sure you are using vector efficiently before making assumptions that the program is "slow".
Regards,
Paul McKenzie
-
Re: Dynamic Memory Allocation Which is best?
Reason behind the search for various methods.
char *kk;
kk = new char[1000];
//Array Use (Copy a .txt file content to a .doc file)
delete []kk;
kk = NULL;
When i use this program runs success.Output is OK But compile in VS2005 with warning level 4 I got following message
Leaking memory 'kk' due to an exception. Consider using a local catch block to clean up memory:
Which method will avoid this problem.....
-
Re: Dynamic Memory Allocation Which is best?
Using std::vector solves that problem. When there´s an exception thrown in the array handling function there will be no cleanup. std::vector will clean up its memory because the vector variable goes out of scope when an exception occurs and its destructor will release the allocated memory. boost::scoped_array may be an alternative.
PS:
vector´s allocation overhead will be neglectible compared to reading a file from disk. Just make sure you don´t have to reallocate multiple times. Resizing the vector to the file´s size before reading into the vector will do only one allocation.
-
Re: Dynamic Memory Allocation Which is best?
1000 bytes is a small amount. Using the stack looks like a good option:
Code:
char kk[1000];
//Array Use (Copy a .txt file content to a .doc file)
If I remember well, with a 32-bit Windows, the stack can contain up to 2 power 32 or 31 bytes, i.e. 2GB, (EDIT: ) or maybe only 1MB, which is good enough for your 1KB buffer.
-
Re: Dynamic Memory Allocation Which is best?
I heard stack is used for function calls . LIFO strategy follows. then how i use stack for allocation because 4 or 5 function calls come,the execution become slow ?
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Dave1024
I heard stack is used for function calls . LIFO strategy follows. then how i use stack for allocation because 4 or 5 function calls come,the execution become slow ?
Did you measure it? It would be great to see your findings.
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Dave1024
Which method will avoid this problem.....
You can follow the compilers recommendation? Or use a vector. Or allocate the array on the stack.
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Dave1024
I heard stack is used for function calls . LIFO strategy follows. then how i use stack for allocation because 4 or 5 function calls come,the execution become slow ?
Your worries are based on a misunderstanding. A stack allocated array is not accessed by pushing and popping some stack. It's accessed the same way as a heap allocated array. And the actual allocation of a stack array is faster.
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Dave1024
I heard stack is used for function calls . LIFO strategy follows. then how i use stack for allocation because 4 or 5 function calls come,the execution become slow ?
When you push something onto the stack, it does NOT copy existing items around within the stack, instead it just uses the next free bytes on the stack. So LIFO is very fast.
-
Re: Dynamic Memory Allocation Which is best?
Hmm, usually I agree with Paul...
What would be the worst case scenario? Having to allocate large quantities of objects with very short lifetime. How to most effectively obtain that? Reuse allocations!!!
vector.resize()???? Common,... no way!!!
new[] and delete[]... in the end, those compilers I've been working with were still calling malloc() and free()... so why not have more control over the code? I'm not ready yet to convert all my codebase to C# or other managed language!
My solution... a simple pool of reusable chunks of memory, and these are the steps:
- malloc() an aligned chunk of memory capable to store a reasonable number of objects; working with segments seems to be still the best solution, since heap managers commit pages in a similar way; it is recommended to limit these allocations to a lower value than the total virtual memory available; when initialization with zero is required, do not use calloc(); might be "evil" :D ; I prefer ZeroMemory(), but memset() might have almost same performance
- use placement new to construct objects of a non-POD type, using pre-allocated memory; it should work as a simple pool and if required, thread-safe; when the pool has memory to reuse, the new instance is constructed at the same address where a released object was, thus reusing the memory; when the pool has no more available chunks, allocate one more, if within the limits designed
- releasing an object consists in calling the destructor of the class, marking the memory as available, and discarding the belonging chunk if completely released
Variations of the above design work better in specific scenarios, but the main idea remains the same. There're many advantages to these kind of implementations, and these I consider the most important:
- avoiding memory fragmentation
- less work for your heap manager which cannot assume which objects being allocated have the same size with previously deleted ones; which of the 2 following loops is faster?
Code:
register unsigned int idx;
int * p = static_cast<int*>(malloc(256 * sizeof(int)));
idx = 1000000;
while (idx) { --idx;
int& c = * new(&p[idx & 0xFF]) int;
c = idx & 0xFF;
// c.~int(); // int doesn't have a destructor, but non-POD types have
}
::free(p);
Code:
register unsigned int idx;
idx = 1000000;
while (idx) { --idx;
int& c = * new int;
c = idx & 0xFF;
delete &c;
}
Regards,
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Bornish
Hmm, usually I agree with Paul...
What would be the worst case scenario? Having to allocate large quantities of objects with very short lifetime. How to most effectively obtain that? Reuse allocations!!!
That is not really the example I'm referring to.
What I'm refering to are the classes that persons create that attempt to do their own memory resizing. For example:
Code:
class foo
{
char *ptr;
public:
void resize(unsigned int num)
{
char *temp = new char [num];
delete [] ptr;
ptr = temp;
}
};
How many times have you seen code written like this? In this case, it is a simple char*, but in other cases it could be any object. Replacing the naive version of resize() with a vector<char> and calling vector::resize() is defacto faster, since vector.resize() doesn't reallocate if it doesn't have to.
Regards,
Paul McKenzie
-
Re: Dynamic Memory Allocation Which is best?
On the other hand, it's not all that difficult to write your own resize function which uses essentially the same algorithm as vector::resize. If you want to do that you can. Still, if you aren't limited to C code, there's little reason *not* to use a std::vector if you can.
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Dave1024
Reason behind the search for various methods.
char *kk;
kk = new char[1000];
//Array Use (Copy a .txt file content to a .doc file)
delete []kk;
kk = NULL;
When i use this program runs success.Output is OK But compile in VS2005 with warning level 4 I got following message
Leaking memory 'kk' due to an exception. Consider using a local catch block to clean up memory:
Which method will avoid this problem.....
Code:
try
{
char* kk = 0;
kk = new char[1000];
// do stuff with your buffer
delete []kk;
kk = NULL;
}
catch()
{
// prevents program from crashing if bad_alloc is thrown.
}
Yes, the catch is empty but it prevents the program from crashing due to unhandled bad_alloc exception. That compiler warning doesn't stop your program from executing the sunny day scenario. It's just telling you that if an exception were to occur, there is no way to catch it.
Worry about writing a program correctly first. Worry about whether it is fast enough later. In this case, I really don't know why we are talking about speed. This is not a complex problem where speed should be an issue. I tend to prefer vectors over arrays because my code looks nicer and the vector provides a convenient object oriented interface which improves the overall quality of the software. I have never had a problem with a vector causing my software to be so slow that it wouldn't work. I'm not saying that it couldn't happen. If it did, you could analyze the program and refactor it. Worrying about which will be faster, before you even write the program and profile it is a complete waste of time in this case.
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Bornish
Having to allocate large quantities of objects with very short lifetime. How to most effectively obtain that? Reuse allocations!!!
Sure, but rarely does this entail writing a pool allocator. For example, if you need a dynamic array within a critical loop, you do not allocate and deallocate the array on each iteration... you simply declare a vector outside of the loop and resize it on each iteration, significantly reducing the number of allocations made. There is also a tendency among developers with a background in Java (et al) to unnecessarily allocate on the heap objects that could have been placed on the stack. Judging by the OP's previous statements about the stack, there's a good chance he's overusing the heap and underusing the stack.
Anyway, to repeat what's already been said, there's no need to be concerned about the speed of a particular allocation if there's no noticeable impact on your program's overall performance. I advise strongly against making any premature optimizations, especially considering statements like the following:
Quote:
Originally Posted by Dave1024
char *kk;
kk = new char[1000];
//Array Use (Copy a .txt file content to a .doc file)
delete []kk;
kk = NULL;
If this function were time-critical, you should be BY FAR more concerned about file operations than heap allocations.
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Hermit
Sure, but rarely does this entail writing a pool allocator. For example, if you need a dynamic array within a critical loop, you do not allocate and deallocate the array on each iteration... you simply declare a vector outside of the loop and resize it on each iteration, significantly reducing the number of allocations made. There is also a tendency among developers with a background in Java (et al) to unnecessarily allocate on the heap objects that could have been placed on the stack. Judging by your previous statements about the stack, there's a good chance you're overusing the heap and underusing the stack.
Anyway, to repeat what's already been said, there's no need to be concerned about the speed of a particular allocation if there's no noticeable impact on your program's overall performance. I advise strongly against making any premature optimizations, especially considering statements like the following:
If this function were time-critical, you should be BY FAR more concerned about file operations than heap allocations.
@Hermit: please do not quote my post and then comment others' posts. The sample loop using placement new was meant to show what happens when a process is using a large number of objects of the same type, but with short lifetime. It usually happens in multi-threaded environments, so most of the application will be "the critical loop" examplified.
@All: personally I hate to work with developers who are not concerned about speed and optimizations; there're no such things as premature optimizations, since real optimizations come from design, which should occur way before having a skeleton implementation; those who first write the code, test and then optimize... at the refactoring stage... well, may be blamed for the ongoing decrease in value of SW devs on the jobs market.
Regards,
-
Re: Dynamic Memory Allocation Which is best?
Using efficient algorithms is very different from squeezing an extra nano-second out of a for-loop.
My only problem with the vector is that it initialises its POD to zero, which make loading an image file into memory unnecessarily inefficient. For such cases I have a very simple buffer class which uses new [] and delete [] internally.
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Bornish
@Hermit: please do not quote my post and then comment others' posts.
:blush: Big apologies, didn't look carefully enough at the names on each post.
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Bornish
@All: personally I hate to work with developers who are not concerned about speed and optimizations; there're no such things as premature optimizations, since real optimizations come from design, which should occur way before having a skeleton implementation; those who first write the code, test and then optimize... at the refactoring stage... well, may be blamed for the ongoing decrease in value of SW devs on the jobs market.
Regards,
Since you are complaining about other people's posts, I'd like to add my 2 cents. I think this is a fairly inflammatory statement, which I totally disagree with. The fastest possible program is not always the best possible program. There is no need to be purposefully wasteful when designing a program but it's difficult to guess what type of performance problems you'll have until you execute it and use a profiler to anaylze performance. You assume that because some are interested in developing interfaces and funciontal implementations first and worrying about speed/optimization after the initial program is running that they are going to produce a poor quality product. That is an inflammatory statement. Then you go on a tirade about a decrease in product and software developer value. That is simply irresponsible in my opinion. I can't believe that this thread would go in this direction over a very simple example (allocating memory for a character array). I can understand talking about this over something more important but in this case we don't even know what the OP's program is required to do. All we've seen is a few lines of code allocating memory for one single char buffer.
-
Re: Dynamic Memory Allocation Which is best?
It's certainly true that, where possible, design choices affecting big-O runtime should be made early and/or encapsulated for easy replacement later. In that sense, optimization is a factor from the very start.
But design choices which don't affect the big-O runtime at all, or affect a non-dominant term, should not be stressed about overmuch until they've been found to be a bottleneck. Little point in cutting the runtime of an O(n^2) loop in half if you've got an O(n^4) loop lurking elsewhere.....
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Dave1024
I am using following ways to Allocate & Deallocate memory dynamically
1. Using malloc() and free ()
2. Using calloc() and free()
3 using new and delete operator
4 using stl <vector>
Ok all are different styles. But i looking the better performence.During the use of stl allocation application is very slow. Multiple times calling of new and delete will reduce the application efficiency.
On the shadow of these points how i choose a way which give optimum use of CPU. Which is the best on first 3 ways ?
In terms of performance, calloc() will initialize allocated memory to 0's so it will be slower than malloc() which initializes nothing.
new(), delete(), and stl<vector> are just adding layers of extra code calls for the C++/STL environment which will also call the same native commands as malloc()/calloc().
But malloc()/free() is for C and new()/delete() is for C++. You should really avoid mix and matching allocation constructs in C++. Not following this principle can open you up for possible ugly security/memory corruption problems in your code. In my opinion, if you want performance, don't write it in C++. Write straight C code. There is a reason why OS's like Solaris and Linux are written primarily in C.
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by kempofighter
Since you are complaining about other people's posts, I'd like to add my 2 cents. I think this is a fairly inflammatory statement, which I totally disagree with. The fastest possible program is not always the best possible program. There is no need to be purposefully wasteful when designing a program but it's difficult to guess what type of performance problems you'll have until you execute it and use a profiler to anaylze performance. You assume that because some are interested in developing interfaces and funciontal implementations first and worrying about speed/optimization after the initial program is running that they are going to produce a poor quality product. That is an inflammatory statement. Then you go on a tirade about a decrease in product and software developer value. That is simply irresponsible in my opinion. I can't believe that this thread would go in this direction over a very simple example (allocating memory for a character array). I can understand talking about this over something more important but in this case we don't even know what the OP's program is required to do. All we've seen is a few lines of code allocating memory for one single char buffer.
@kempofighter:Thanks for your reply; I like to see different opinions. I don't understand why did you feel offended by mine, though. I've started my statement with "personally..." so it is my write to have an opinion and to like or hate working with someone, especially when provided the reason for it. Inflammatory? Don't think was more then replying to a question about performance with a strong advise against making any premature optimizations! I can't agree with that since I've started programming on paper (>18 yrs ago), with no "performance tools" to help identify bottlenecks, and at the national olympics, the first eliminatory test was based on how performant (speed and memory used) was our implementation, since most participants were having perfect output results. You see, they needed only a handful of people for the final practical test, since were not enough computers (small / stupid country ;) ).
I'd like to clarify something: I wasn't really taking about fastest implementation... more of a more responsiveness one. Also, you may notice in this thread and others, that are quite many developers quite concerned about optimizations and the current trend in SW production. I'm not saying everyone should agree with these observations.
To reverse the "highjacking" of this thread, I think I understood Dave's original post: better performance with dynamic allocated memory using malloc, calloc, new & delete, or vector class? I gave him my answer: placement new after malloc! Why? Because is more important how you use the heap manager, not how you call it!
PS: we could continue this friendly discussion in pvt if you'd like, so we no longer highjack this thread; just send me a msg.
Best regards,
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by why2jjj
In my opinion, if you want performance, don't write it in C++. Write straight C code.
This I don't understand whatsoever. Whatever you can do in 'C' can be done in C++. Nothing stops you from doing 'C' code in a C++ program.
Regards,
Paul McKenzie
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Paul McKenzie
This I don't understand whatsoever. Whatever you can do in 'C' can be done in C++. Nothing stops you from doing 'C' code in a C++ program.
I totally agree with you Paul! ;)
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Bornish
I think I understood Dave's original post: better performance with dynamic allocated memory using malloc, calloc, new & delete, or vector class? I gave him my answer: placement new after malloc! Why? Because is more important how you use the heap manager, not how you call it!
Did you consider the possibility of being able to use a custom allocator using std::vector since you are so straightforwardly ruling it out? When the design is good, you can fit in optimizations/changes pretty easily and hence the term premature optimization has been coined and is stressed upon. Such is the design of STL and STL-like containers that you can easily replace the default allocator if the allocation scheme is found out to be the bottleneck.
If its found out that pool allocation strategy might help optimize the memory allocations, one could drop out the default std::allocator and use something like boost::pool_allocator<T> which can bind seamlessly to the container.
I agree with you in that one should not code blindly or in complete ignorance but std::vector is such a solution that can adapt to any allocation scheme that you might find effective. Using raw memory allocation and using placement new is good if it adds to performance but the allocation scheme should be another encapsulated layer, out of the logic being applied to solve the business problem. It keeps the code more maintainable and clearer and flexible to changes that might come in. Of course, that is my opinion and you are free to disagree. :)
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Paul McKenzie
This I don't understand whatsoever. Whatever you can do in 'C' can be done in C++. Nothing stops you from doing 'C' code in a C++ program.
Regards,
Paul McKenzie
What I meant by this is years ago when I was looking at code optimization in terms of the number of lines of assembly generated between a C++ program and a comparable C program, C was more optimized. Solaris and Linux OS coders don't necessarily write OS functionality in C++ because they are scared to death that the resulting # of lines of assembly from a C++ program will be more than a C program and kill performance because there is more lines of assembly to execute in a program.
Now compilers can be way better now, but that is still a belief.
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by why2jjj
What I meant by this is years ago when I was looking at code optimization in terms of the number of lines of assembly generated between a C++ program and a comparable C program,
So you're saying that this program:
Code:
#include <stdio.h>
int main()
{
printf("Hello World");
}
Compiled as "main.cpp" will be different than the same program compiled as "main.c"?
Most C++ compilers are also 'C' compilers. When these compilers encounter a file extension of ".c", the 'C' language parser is used, and the rules of 'C' take over. Therefore I am highly skeptical that the very same compiler compiling the very same code will produce different object code, depending on whether it is compiled in C++ mode or 'C' mode.
If you're refering to using C++ language features, that is not what I'm saying. I'm saying that line by line, the very same 'C' program can be compiled as C++ (making sure that the 'C' program prototyped functions, and do not use C++ keywords such as "class", "new", etc.), and there should be no difference.
Regards,
Paul McKenzie
-
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Bornish
PS: we could continue this friendly discussion in pvt if you'd like, so we no longer highjack this thread; just send me a msg.
Best regards,
I don't think that is necessary. I think it is an important discussion to have. One of the beautiful things about OO design and the new capabilities that C++ provides is the ability to refactor a good design. I've been involved with writing large scale, embedded applications as well as windows applications in C++. I can appreciate the concern people have about a vector zero initializing large chunks of data, for instance. So long as you understand the limitations of these tools, you should still be able to write a very high performance program using object oriented programs. The fact that malloc/free might be slightly faster than new/delete is not a good enough reason to choose those mechanisms in a C++ program. While performance is important, I also believe that it is possible to spend way too much time worrying about very trivial things.
Quote:
Originally Posted by why2jjj
In my opinion, if you want performance, don't write it in C++. Write straight C code.
It's very possible to write a program in C++ that will meet the requirements of a system that requires high performance. It's also true that sometimes you sacrifice speed in order to gain other advantages. Sure, you could write program that is written in C that also meets the requirements (and gain some performance advantages) but you have to give up many of the advantages that the C++ language provides.
Obviously, reasonable people can disagree over these things. That's my final 2 cents on the matter.