473,511 Members | 14,933 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

fast array copy

Hello,

I'm writing a function that updates an array. That is, given an
array, change each element.

The trick is this: I can't change any elements until I've processed
the entire array. For example, the manner in which I update element 1
depends on several other (randomly numbered) elements in the array.
So, I can't change an element until I've figured out how every element
changes.

To do this, I am simply creating a duplicate array and writing the new
values in that array. When I'm done, I copy the new array over the
old one. My question is, what's the best way of doing this?

The (seemingly) naive way is to copy the elements from the new over
the old array one-by-one. For example:

double h[SIZE];
void update()
{
double hnew[SIZE];
// do stuff to populate hnew
memcpy(h,hnew,SIZE*sizeof(double));
}
However, since arrays are pointers, it seems like it'd be much more
efficient to just change where the pointer is pointing. For example:

double h[SIZE];
void update(double* hnew)
{
// do stuff to populate hnew
delete(h);
h = hnew;
}

This requires relying on the caller to allocate memory for hnew.

Is the pointer method better? Does anyone have any better ideas?

Thanks,
Mark
Nov 14 '05 #1
7 7374
simkn wrote:


I'm writing a function that updates an array.
That is, given an array, change each element.

The trick is this: I can't change any elements until I've processed
the entire array. For example, the manner in which I update element 1
depends on several other (randomly numbered) elements in the array.
So, I can't change an element
until I've figured out how every element changes.

To do this, I am simply creating a duplicate array and writing the new
values in that array. When I'm done, I copy the new array over the
old one. My question is, what's the best way of doing this?

The (seemingly) naive way is to copy the elements from the new over
the old array one-by-one. For example:

double h[SIZE];
void update()
{
double hnew[SIZE];
// do stuff to populate hnew
memcpy(h,hnew,SIZE*sizeof(double));
}
However, since arrays are pointers, it seems like it'd be much more
efficient to just change where the pointer is pointing. For example:

double h[SIZE];
void update(double* hnew)
{
// do stuff to populate hnew
delete(h);
h = hnew;
}

This requires relying on the caller to allocate memory for hnew.

Is the pointer method better? Does anyone have any better ideas?


double* update(size_t size, double h[size]) {
double hnew[size];
// do stuff to populate hnew
memcpy(h, hnew, size*sizeof(double));
return h;
}

Nov 14 '05 #2
"simkn" <ma**********@gmail.com> wrote in message
news:25**************************@posting.google.c om...
Hello,

I'm writing a function that updates an array. That is, given an
array, change each element.

The trick is this: I can't change any elements until I've processed
the entire array. For example, the manner in which I update element 1
depends on several other (randomly numbered) elements in the array.
So, I can't change an element until I've figured out how every element
changes.

To do this, I am simply creating a duplicate array and writing the new
values in that array. When I'm done, I copy the new array over the
old one. My question is, what's the best way of doing this?

The (seemingly) naive way is to copy the elements from the new over
the old array one-by-one. For example:

double h[SIZE];
void update()
{
double hnew[SIZE];
// do stuff to populate hnew
memcpy(h,hnew,SIZE*sizeof(double));
better yet : memcpy(h, hnew, sizeof(h));
}
However, since arrays are pointers, it seems like it'd be much more
efficient to just change where the pointer is pointing. For example:
NONONONO : arrays are not pointers.
but you can use pointers to arrays to avoid the final copying step.
double h[SIZE];
void update(double* hnew)
{
// do stuff to populate hnew
delete(h); Do you mean the C++ delete operator ? even C++ won't let you do that. h = hnew; Both C and C++ will refuse to compile this.
}

This requires relying on the caller to allocate memory for hnew.
Is the pointer method better? Does anyone have any better ideas?


Doing it with pointers is OK, but you have to be consistent in your memory
allocation scheme.
And allocating memory with malloc is definitely less efficient than defining an
automatic array.
It might even be less efficient than the copying stage it saves.

This is an example with pointers :

double *h;

int main() {
...
/* initialization of h */
h = malloc(SIZE * sizeof(*h));
for (int i = 0; i < SIZE; i++) {
h[i] = some_initial_value...
}
...
}

void update() {
double *hnew;
hnew = malloc(SIZE * sizeof(*hnew));
/* do stuff to populate hnew */

free(h);
h = hnew;
}

Another caveat with this method is error checking, that I left out, but must be
written in a real world program.

Chqrlie.
Nov 14 '05 #3
simkn wrote:
Hello,

I'm writing a function that updates an array. That is, given an
array, change each element.

The trick is this: I can't change any elements until I've processed
the entire array. For example, the manner in which I update element 1
depends on several other (randomly numbered) elements in the array.
So, I can't change an element until I've figured out how every element
changes.

To do this, I am simply creating a duplicate array and writing the new
values in that array. When I'm done, I copy the new array over the
old one. My question is, what's the best way of doing this?

The (seemingly) naive way is to copy the elements from the new over
the old array one-by-one. For example:

double h[SIZE];
void update()
{
double hnew[SIZE];
// do stuff to populate hnew
memcpy(h,hnew,SIZE*sizeof(double));
Nitpick: Write the third argument as `sizeof h'.
At the very least, write `SIZE * sizeof h[0]'. The
reasons are the same as those given in connection
with the argument to malloc().
}
However, since arrays are pointers, it seems like it'd be much more
efficient to just change where the pointer is pointing. For example:

double h[SIZE];
void update(double* hnew)
{
// do stuff to populate hnew
delete(h);
h = hnew;
}

This requires relying on the caller to allocate memory for hnew.

Is the pointer method better? Does anyone have any better ideas?


What language are you using? If it's C++, ignore the
C answer I'm about to write and take your question to
comp.lang.c++ instead.

As written, the code won't work at all: The line
`h = hnew' will not compile. `h' is an array, and arrays
are not assignable.

You could, however, use pointers throughout instead of
trying to mix pointers and arrays. Something like this
could be done:

double h1[SIZE], h2[SIZE];
double *hcurr = h1, *hnext = h2;

void update(void) {
/* Compute `hnext' values from `hcurr' values */
...

/* Swap the "next" and "current" roles */
hcurr = hnext;
hnext = (hcurr == h1) ? h2 : h1;
}

--
Er*********@sun.com

Nov 14 '05 #4
>Hello,

I'm writing a function that updates an array. That is, given an
array, change each element.

The trick is this: I can't change any elements until I've processed
the entire array. For example, the manner in which I update element 1
depends on several other (randomly numbered) elements in the array.
So, I can't change an element until I've figured out how every element
changes.

To do this, I am simply creating a duplicate array and writing the new
values in that array. When I'm done, I copy the new array over the
old one. My question is, what's the best way of doing this?
In article <25**************************@posting.google.com >
simkn <ma**********@gmail.com> wrote:The (seemingly) naive way [to put the new values back into an
existing array] is to copy the elements from the new over
the old array one-by-one. ...
That will indeed work:
double h[SIZE];
void update()
{
double hnew[SIZE];
// do stuff to populate hnew
memcpy(h,hnew,SIZE*sizeof(double));
}
Or, simpler:

memcpy(h, hnew, sizeof h);
However, since arrays are pointers ...
But arrays are not pointers. You might as well start with "since
cows are hamburger". Cows are not hamburger, and a pile of ground
beef cannot do everything a cow can do.

It *is* true that the "good stuff" you get with arrays is basically
as useful as the "good stuff" you get with pointers. If you just
want the protein, the bones and other bits in a cow just get in
the way. But while you only may *want* the one part or the other,
never mistake the one *for* the other.
it seems like it'd be much more
efficient to just change where the pointer is pointing.
You can do that, provided you have a pointer (not an array) *and*
sufficient memory to which the pointer can point.
For example:

double h[SIZE];
void update(double* hnew)
{
// do stuff to populate hnew
delete(h);
h = hnew;
}

This requires relying on the caller to allocate memory for hnew.
This also does not work, because h is still an array. C forbids
the assignment (h is not a "modifiable lvalue", in standard-ese).

Note that if you use a pointer, it takes *more* space than if
you just use an array, because the pointer itself requires space,
and you still need just as much space as you used to have in the
array. Consider the two versions diagrammatically:

(A) array version:

+---------------------------------+
| big chunk of memory |
+---------------------------------+

(B) pointer version:

+---------------------------------+
| big chunk of memory |
+---------------------------------+
^
| +---+
+-------------------|-* | tiny little pointer
+---+
Is the pointer method better?
"Better" is subjective; but if your application currently spends
a lot of time copying memory from hnew to h, and you can remove
all the "copy" time, your application may run noticeably faster.
Does anyone have any better ideas?


"Better" is subjective... :-)

Note that regardless of which version (array or pointer) you have
above, you *also* need, at least temporarily, a second "big chunk
of memory" (hnew -- whether this is another array, or a pointer
plus a chunk of memory it points to) to hold all the new values.
If there is no reason not to leave that big chunk of memory around
all the time, you can simply make *two* arrays:

(C) two-array version:

+---------------------------------+
| big chunk of memory |
+---------------------------------+

+---------------------------------+
| big chunk of memory |
+---------------------------------+

Now you just need a way to select which of the two arrays to use.
You can do this with a pointer, and point it to either array, or
with a simple two-valued variable:

double array0[SIZE], array1[SIZE];
int which_array = 0;
...
which_array = 1 - which_array; /* from 0 to 1, or 1 to 0 */

Of course, writing:

if (which_array == 0)
... array0[i] ...
else
... array1[i] ...

is a pain -- but it is also unnecessary. Just make your two arrays
into a single variable, by using an array of two arrays:

(D) array of two arrays version:

+---------------------------------+
| big chunk of memory |
+---------------------------------+
| big chunk of memory |
+---------------------------------+

double array[2][SIZE];
int which_array = 0;
...
which_array = 1 - which_array; /* from 0 to 1, or 1 to 0 */

... array[which_array][i] ...

Alternatively, use that "tiny little pointer", along with the arrays.
This works with both arrangements (C) and (D):

(C):
which_array = 1 - which_array;
ptr = (which_array == 0 ? &array0[0] : &array1[0]);

(D):
which_array = 1 - which_array;
ptr = &array[which_array][0];

Instead of actual arrays, of course, if you have pointers, you can
use malloc():

#include <stdlib.h>

double *mem_blob_0, *mem_blob_1;
...
mem_blob_0 = malloc(SIZE * sizeof *mem_blob_0);
mem_blob_1 = malloc(SIZE * sizeof *mem_blob_1);

or an array of two pointers:

double *mem_blob[2];
...
mem_blob[0] = malloc(SIZE * sizeof *mem_blob[0]);
mem_blob[1] = malloc(SIZE * sizeof *mem_blob[1]);

and/or you can get twice as much memory with a single malloc():

double *mem_blob_of_twice_the_size;
...
mem_blob_times_two = malloc(2 * SIZE * sizeof *mem_blob_times_two);

after which something like:

double *p = &mem_blob_times_two[SIZE];
/* or: = mem_blob_times_two + SIZE; */

gets you the "second half".

Of all these methods, which one is the best? "Best" is subjective....
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #5
simkn wrote:
...
However, since arrays are pointers, it seems like it'd be much more
efficient to just change where the pointer is pointing. For example:

double h[SIZE];
void update(double* hnew)
{
// do stuff to populate hnew
delete(h);
h = hnew;
}

This requires relying on the caller to allocate memory for hnew.

Is the pointer method better? Does anyone have any better ideas?
...


There's no "pointer method". Arrays are _not_ pointers, which means that
there's no way to "just change where the pointer is pointing". Read the
FAQ about arrays, look up some information on the net or get yourself a
good C book.

--
Best regards,
Andrey Tarasevich

Nov 14 '05 #6

"simkn" <ma**********@gmail.com> wrote in message
news:25**************************@posting.google.c om...

However, since arrays are pointers, it seems like it'd be much more
efficient to just change where the pointer is pointing. For example:

double h[SIZE];
void update(double* hnew)
{
// do stuff to populate hnew
delete(h);
h = hnew;
}


No, arrays are not pointers. This will not work. Even if you change the
array to be a pointer to an array to make it work, you will probably find
that the allocation/deallocation takes more time than simply copying the
array.

Is the size of the array constant? Then just keep two of them, and use a
pointer to an array to swap between them each time you do an update.

DrX
Nov 14 '05 #7
On Thu, 18 Nov 2004 20:43:46 UTC, ma**********@gmail.com (simkn)
wrote:
Hello,

I'm writing a function that updates an array. That is, given an
array, change each element.

The trick is this: I can't change any elements until I've processed
the entire array. For example, the manner in which I update element 1
depends on several other (randomly numbered) elements in the array.
So, I can't change an element until I've figured out how every element
changes.

To do this, I am simply creating a duplicate array and writing the new
values in that array. When I'm done, I copy the new array over the
old one. My question is, what's the best way of doing this?

The (seemingly) naive way is to copy the elements from the new over
the old array one-by-one. For example:

double h[SIZE];
void update()
{
double hnew[SIZE];
// do stuff to populate hnew
memcpy(h,hnew,SIZE*sizeof(double));
}
However, since arrays are pointers, it seems like it'd be much more
efficient to just change where the pointer is pointing.
No, a pointer NOT an array and an array is NOT a pointer. An Array is
an array - even as the address opf an array(member) is a pointer.

For example:
double h[SIZE];
void update(double* hnew)
{
// do stuff to populate hnew
delete(h);
h = hnew;
}

This requires relying on the caller to allocate memory for hnew.

Is the pointer method better? Does anyone have any better ideas?

Thanks,
Mark


You describes lists, not arrays, sou you should create a list of
objects instead an a simple array, because reordering or resizing a
list is much easier than reordering an array.

There are some types of lists you can use depending on the type of
work you have to do on:
- single linked list: designed to work straight forward on
- double linked list: go through in both directions quickly
- tree: insert, remove, sort, search
makes search quick
can easy malformed to an double linked list,
making search really time intensive
- AVL tree: sorted insert, remove, search(, resort)
like simple tree but extended to hold
each branch in (nearly) same deep
making search really quick,

to name only the most common used types.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

Nov 14 '05 #8

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

Similar topics

4
12035
by: stelladiary2004 | last post by:
Hi! I would appreciate some help with this (basic) question. I need to copy an 2D array x to another 2D array y. I know how to do it copying element by element, but I would like to use a faster...
20
9110
by: GS | last post by:
The stdint.h header definition mentions five integer categories, 1) exact width, eg., int32_t 2) at least as wide as, eg., int_least32_t 3) as fast as possible but at least as wide as, eg.,...
9
2057
by: Peter Olcott | last post by:
// // Array2D.h 2005-11-27 5:50 AM // #define UINT unsigned int // // // class ArrayType2D { private: int Width;
10
2974
by: javuchi | last post by:
I just want to share some code with you, and have some comments and improvements if you want. This header file allocates and add and delete items of any kind of data from a very fast array: ...
15
18698
by: Michael A. Covington | last post by:
Any thoughts about how to implement image processing algorithms to run fast in C#? Using GetPixel to access every pixel from a Bitmap seems to be rather time-consuming.
95
4959
by: hstagni | last post by:
Where can I find a library to created text-based windows applications? Im looking for a library that can make windows and buttons inside console.. Many old apps were make like this, i guess ...
2
4003
by: barker7 | last post by:
I use a simple double array plus a variable to store the row size to represent two dimensional data. I need to quickly copy this data to a two dimensional array: double. Currently I iterate...
3
6207
by: satishknight | last post by:
Hi, Can some one tell me how to change the validation sequence for the code pasted below, actually what I want it when any one enters the wrong login information (already registered users) then it...
7
3609
by: fr33host | last post by:
Dear developers, I have a question. Is there a faster array copy than a for loop. What would you suggest for this code sample? void get(char* src, char* dest, int i) { for (int j = 0; j <...
0
7137
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
7417
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...
1
7074
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
5659
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5063
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3219
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3210
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
780
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
445
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.