2

Using C# (and Visual Studio 2010), I defined a struct of 5 bools (and nothing else). Then I created an array of 16515072 elements of that struct. Strangely, the ANTS Memory profiler shows that this array is occupying more than 80 MB of memory.

However, if the bits where perfectly packed it should only occupy ~10 MB. Even if the 5 bools were packed into (encoded by) a single byte (which I would expect), the array should only be ~16 MB.

How can I improve the packing of the array in order to reduce the memory it occypies? Are there any general best-pactices when optimizing the memory footprint of large arrays?

2
  • 4
    Each bool is taking a separate byte. There is no automatic packing optimization. Commented Sep 2, 2013 at 0:38
  • 1
    Each bool takes one byte, so total memory is 5 * 16515072 B = 82575360 B = 82 MB Commented Sep 2, 2013 at 11:20

1 Answer 1

3

The results that you get are correct: in C# .NET bools are not packed - each one occupies a single byte, so the total is 16515072*5=82MB.

If you would like to pack the booleans into bits, you can use a single byte for storing the values, and use bit operations for your getters and setters:

private byte storage;
public bool Property1 {
    get {
        return (storage & 0x01) != 0;
    }
    set {
        if (value) {
            storage |= 0x01;
        } else {
            storage &= 0xFE;
        }
    }
}
public bool Property2 {
    get {
        return (storage & 0x02) != 0;
    }
    set {
        if (value) {
            storage |= 0x02;
        } else {
            storage &= 0xFD;
        }
    }
}
public bool Property3 {
    get {
        return (storage & 0x04) != 0;
    }
    set {
        if (value) {
            storage |= 0x04;
        } else {
            storage &= 0xFB;
        }
    }
}

Continue using powers of 2 for bit masks of the remaining properties - 0x08, 0x10, 0x20, and so on.

Sign up to request clarification or add additional context in comments.

8 Comments

Thank you, I was not aware of that. I expected that the struct was automatically packed (isn't this the case in C++?). Could anyone maybe comment on the performance of the suggested packing code suggested by dasblinkenlight? Shouldn't this be even faster than using the struct as converting the bits into bytes (and back) seems more work than accessing a single bit in a byte (given the efficiency of both depends on the compiler)?
@pad_ares C++ and C# have nothing in common except for some syntax and the "C" in the name. And the performance of ANY code is fine unless it turns out to be a bottle-neck in a real-life scenario.
@pad_ares I don't think that C/C++ uses bit packing by default (although the language provides facilities for packing bits if you wish). Since a byte is the smallest addressable unit in memory, packing would necessarily use code similar to what I suggested, perhaps utilizing more specific CPU instructions where available.
ubyte? Not in C#. I think you meant byte.
@pad_ares I hard-coded the results of inversion in the edit to avoid this error.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.