|
|
|
#1 (permalink) |
|
Messages: n/a
Hébergeur: |
Hello all,
I have a 'good practice' question. Lately I've been using a lot of functions such as this: void Func(int Size, double *Array) { static double *Transformed=NULL; Transformed=realloc(Transformed, Size*sizeof(double)); // Do something from Array to Transformed } Now if the value of Size changes a lot between calls, the resulting prog is poorly optimized (it reallocates each time). I'm ok with that. Ignoring the fact that the memory is never freed, if the value of Size changes seldom, does the call to realloc wastes time then ? -- Guillaume Dargaud http://www.gdargaud.net/ |
|
|
|
#2 (permalink) |
|
Messages: n/a
Hébergeur: |
On Oct 18, 10:02 am, "Guillaume Dargaud"
<use_the_form_on_my_contact_p...@www.gdargaud.ne t> wrote: > Hello all, > I have a 'good practice' question. > Lately I've been using a lot of functions such as this: > > void Func(int Size, double *Array) { > static double *Transformed=NULL; > Transformed=realloc(Transformed, Size*sizeof(double)); > // Do something from Array to Transformed > > } > > Now if the value of Size changes a lot between calls, the resulting prog is > poorly optimized (it reallocates each time). I'm ok with that. > Ignoring the fact that the memory is never freed, if the value of Size > changes seldom, does the call to realloc wastes time then ? It depends. realloc will often be clever enough to realise that it can just use the previous block of data without any change. So if you pass in the same Size or similar Size values (like 10000, 10001, 9999) it will be fast. However, if a new block is allocated, all the data will be copied from the previous block to the new block, because that is what realloc does. That might be quite wasteful. You might just add another variable "static int allocatedSize = 0", compare new and old size and only realloc when it gets bigger. |
|
|
|
#3 (permalink) |
|
Messages: n/a
Hébergeur: |
On Oct 18, 1:28 pm, "christian.bau" <christian....@cbau.wanadoo.co.uk>
wrote: > It depends. realloc will often be clever enough to realise that it can > just use the previous block of data without any change. So if you pass > in the same Size or similar Size values (like 10000, 10001, 9999) it > will be fast. However, if a new block is allocated, all the data will > be copied from the previous block to the new block, because that is > what realloc does. That might be quite wasteful. realloc tries not to copy the data, just resize the available block of memory. > Note that realloc() *may* move the memory allocation resulting in a different return value than ptr. |
|
|
|
#4 (permalink) |
|
Messages: n/a
Hébergeur: |
On Oct 18, 11:28 am, "christian.bau"
<christian....@cbau.wanadoo.co.uk> wrote: > On Oct 18, 10:02 am, "Guillaume Dargaud" > > <use_the_form_on_my_contact_p...@www.gdargaud.ne t> wrote: > > Hello all, > > I have a 'good practice' question. > > Lately I've been using a lot of functions such as this: > > > void Func(int Size, double *Array) { > > static double *Transformed=NULL; > > Transformed=realloc(Transformed, Size*sizeof(double)); > > // Do something from Array to Transformed > > > } > > > Now if the value of Size changes a lot between calls, the resulting prog is > > poorly optimized (it reallocates each time). I'm ok with that. > > Ignoring the fact that the memory is never freed, if the value of Size > > changes seldom, does the call to realloc wastes time then ? If you're ok with the fact that the function calls realloc each time, then which waste of time are you worried about ? Leaving your question aside there are a couple of problems with the function. It would be better to make Size of type size_t. You need to make sure that the expression Size*sizeof(double) does not overflow before you pass it to realloc. > You might just add another variable "static int allocatedSize = 0", > compare new and old size and only realloc when it gets bigger. I second that apart from the fact that allocatedSize also needs to be size_t. |
|
|
|
#5 (permalink) |
|
Messages: n/a
Hébergeur: |
vipvipvipvip.ru@gmail.com wrote:
> realloc tries not to copy the data, just resize the available block of > memory. Does the standard enforce this? Otherwise you are simply discussing what some (possibly all, but I doubt you could prove that) implementations do. |
|
|
|
#6 (permalink) |
|
Messages: n/a
Hébergeur: |
Mark Bluemel said:
> vipvipvipvip.ru@gmail.com wrote: > >> realloc tries not to copy the data, just resize the available block of >> memory. > > Does the standard enforce this? No. > Otherwise you are simply discussing what > some (possibly all, but I doubt you could prove that) implementations do. Right. -- Richard Heathfield <http://www.cpax.org.uk> Email: -http://www. +rjh@ Google users: <http://www.cpax.org.uk/prg/writings/googly.php> "Usenet is a strange place" - dmr 29 July 1999 |
|
|
|
#7 (permalink) |
|
Messages: n/a
Hébergeur: |
vipvipvipvip.ru@gmail.com wrote:
> "christian.bau" <christian....@cbau.wanadoo.co.uk> wrote: > >> It depends. realloc will often be clever enough to realise that >> it can just use the previous block of data without any change. >> So if you pass in the same Size or similar Size values (like >> 10000, 10001, 9999) it will be fast. However, if a new block is >> allocated, all the data will be copied from the previous block >> to the new block, because that is what realloc does. That might >> be quite wasteful. > > realloc tries not to copy the data, just resize the available > block of memory. That depends on the malloc/free/realloc package, and is not guaranteed. One package that goes to lengths to avoid copying is nmalloc for DJGPP and similar, available at: <http://cbfalconer.home.att.net/download/> -- Chuck F (cbfalconer at maineline dot net) Available for consulting/temporary embedded and systems. <http://cbfalconer.home.att.net> -- Posted via a free Usenet account from http://www.teranews.com |
|
|
|
#8 (permalink) |
|
Messages: n/a
Hébergeur: |
Guillaume Dargaud wrote:
> > Hello all, > I have a 'good practice' question. > Lately I've been using a lot of functions such as this: > > void Func(int Size, double *Array) { > static double *Transformed=NULL; > Transformed=realloc(Transformed, Size*sizeof(double)); > // Do something from Array to Transformed > } > > Now if the value of Size changes a lot between calls, the resulting prog is > poorly optimized (it reallocates each time). I'm ok with that. > Ignoring the fact that the memory is never freed, if the value of Size > changes seldom, does the call to realloc wastes time then ? I would suspect that any decent realloc() would, once it sees that the old size and new size are identical, simply return the current pointer. (It must determine the old size at some point, in order to perform its duties. Even a suboptimal "call malloc, memcpy the buffer, and then free the original" routine needs to know the old size.) If you're that concerned, you can always keep track of the old size, and skip the realloc() if it didn't change: void Func(int Size, double *Array) { static double *Transformed = NULL; static int OldSize = 0; ASSERT( Size != 0 ); /* What do we want to do about zero size? */ if ( Size != OldSize ) { Transformed = realloc(Transformed, Size*sizeof(*Transformed)); OldSize = Size; } /* Do something from Array to Transformed */ } If you're not concerned about "wasted memory", you could even change the realloc-condition to: if ( Size > OldSize ) Then, it will only realloc if the buffer needs to grow. Finally, if you don't need the current contents of Transformed, it may be more efficient to call free/malloc instead, as this skips the copy. -- +-------------------------+--------------------+-----------------------+ | Kenneth J. Brody | www.hvcomputer.com | #include | | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> | +-------------------------+--------------------+-----------------------+ Don't e-mail me at: <mailto:ThisIsASpamTrap@gmail.com> |
|
![]() |
| Outils de la discussion | |
|
|