views:

68

answers:

4

I need to remove every fourth byte in the byte[] I have. Is there some built-in function that could help me to do that or do I have to loop over the array picking and moving each byte one by one?

Similarly what what if I need to place 0 after every three bytes from byte[] is there a way to do this faster than manually?

+1  A: 

Sounds like a good job for a parallel For loop (assuming you can use .NET 4).

Steve Danner
A: 

The fastest way would probably be to create a wrapper to translate indexes instead of creating a new array.

Lee
I need new array because after that I'd like to do File.WriteAllBytes() fast or even use some low functions from kernel32 to write it as fast as possible.
Kamil Szot
+3  A: 

Coding it by hand is likely to be very fast, and the bottleneck is the cpu-to-memory bandwidth.

One core can easily max out the memory bandwidth on a modern machine, so multithreading is unlikely to help since the work done is very straightforward (a single read or write per 4th element.)

mdma
I ran some tests. Copying byte array, byte by byte with simple for loop is at least two times slower than copy done with (byte[])arr.Clone() despite the fact that Clone not only copies but also allocates and on slower machine ratio is even bigger (6 times).
Kamil Szot
Did you try with every 4th element? I think the difference is there.
mdma
Also, you are writing to disk (via memory mapped I/O I guesssss.) this will overshadow any differences in direct memory performance. Even though your hand coded is 1/2 the speed of .NET Clone(), you have to set 1/4 of the memory and save to disk. Memory is many 1000x faster than disk - you will not see a difference in practice,
mdma
+1  A: 

If you don't mind creating a new array instead of modifying the existing one, you can easily do it with Linq:

bytes = bytes.Where((b, i) => (i + 1) % 4 != 0).ToArray();

To insert an item every 3 bytes, there is no way to do it using built-in extension methods. But you can create your own extension method:

public static IEnumerable<T> InsertEvery<T>(this IEnumerable<T> source, T valueToInsert, int frequency)
{
    int n = 0;
    foreach (var item in source)
    {
        if ((n + 1) % frequency == 0)
            yield return valueToInsert;
        yield return item;
        n++;
    }
}

...

bytes = bytes.InsertEvery(0, 3).ToArray();

By the way, are your 2 questions related to the same array ? i.e. you want to remove every fourth byte, then insert 0 every 3 bytes, all in the same array ? In that case, what you really want to do is to replace every fourth byte with 0, and the most efficient way to do it is to use a for loop:

for(int i = 3; i < bytes.Length; i += 4)
{
    bytes[i] = 0;
}
Thomas Levesque
How about the second part of my question? How to insert new byte after every three existing bytes?
Kamil Szot
Although this is an elegant way, it is far from the fastest.
Trillian
@Kamil, see my updated answer.
Thomas Levesque
Thanks. Very nice. And no, this is same array but it will be stripped of every fourth char, written to disk and at some unspecified point in the future read from disk and padded after every third char with 0.
Kamil Szot