C compilers like D compilers will pack a struct of two 16-bit words into a 32-bit type if you don't force an alignment: http://dlang.org/attribute.html#align What you should avoid is having a data type start at an address that is not a multiple of its size, especially when it comes to SIMD. Working with 16-bit values is not really supported in todays x86 CPUs though, and integer math in D typically yields ints even when you use smaller data types, reflecting what happens on the hardware. Usually I use uint, size_t, real for things that will go to CPU registers and the smallest data type that will work for storage in memory. Keep in mind that RAM access is slow compared to how fast CPUs run. It can be beneficial to have "slower" data types if they allow more data to fit into the CPU cache.
Typically you sort the fields of a struct by size with the larger ones (e.g. pointers) at the top followed by ints, shorts and finally bytes if you want to conserve memory. There is even a template to do that for you, but I think it is more of a toy, when you can easily do that manually without the clutter: http://dlang.org/phobos/std_typecons.html#.alignForSize