Question: I have a byte array containing 16 & 32bit data samples, and to cast them to Int16 and Int32 I currently just do a memcpy with 2 (or 4) bytes.

Because memcpy is probably isn't optimized for lenghts of just two bytes, I was wondering if it would be more efficient to convert the bytes using integer arithmetic (or an union) to an Int32.

I would like to know what the effiency of calling memcpy vs bit shifting is, because the code runs on an embedded platform.

Answer: 
I would say that `memcpy` is not the way to do this. However, finding the *best* way depends heavily on how your data is stored in memory.

To start with, you don't want to take the address of your destination variable. If it is a local variable, you will force it to the stack rather than giving the compiler the option to place it in a processor register. This alone could be very expensive.

The most general solution is to read the data byte by byte and arithmetically combine the result. For example:

```
uint16_t res = (  (((uint16_t)char_array[high]) << 8)
                | char_array[low]);

```

The expression in the 32 bit case is a bit more complex, as you have more alternatives. You might want to check the assembler output which is best.

Alt 1: Build paris, and combine them:

```
uint16_t low16 = ... as example above ...;
uint16_t high16 = ... as example above ...;
uint32_t res = (  (((uint32_t)high16) << 16)
                | low16);

```

Alt 2: Shift in 8 bits at a time:

```
uint32_t res = char_array[i0];
res = (res << 8) | char_array[i1];
res = (res << 8) | char_array[i2];
res = (res << 8) | char_array[i3];

```

All examples above are neutral to the endianess of the processor used, as the index values decide which part to read.

Next kind of solutions is possible if 1) the endianess (byte order) of the device match the order in which the bytes are stored in the array, and 2) the array is known to be placed on an aligned memory address. The latter case depends on the machine, but you are safe if the char array representing a 16 bit array starts on an even address and in the 32 bit case it should start on an address dividable by four. In this case you could simply read the address, after some pointer tricks:

```
uint16_t res = *(uint16_t *)&char_array[xxx];

```

Where `xxx` is the array index corresponding to the first byte in memory. Note that this might not be the same as the index to he lowest value.

I would strongly suggest the first class of solutions, as it is endianess-neutral.

Anyway, both of them are way faster than your `memcpy` solution.
`memcpy` is not valid for "shifting" (moving data by an offset shorter than its length within the same array); attempting to use it for such invokes very dangerous undefined behavior. See <http://lwn.net/Articles/414467/>

You must either use `memmove` or your own shifting loop. For sizes above about 64 bytes, I would expect `memmove` to be a lot faster. For extremely short shifts, your own loop may win. Note that `memmove` has more overhead than `memcpy` because it has to determine which direction of copying is safe. Your own loop already knows (presumably) which direction is safe, so it can avoid an extra runtime check.