As far as code efficiency goes, if you expect the operation to be performed to be the same, then I would expect the compiler to generate the same code, hence no difference in runtime efficiency.
If that's not the case, then the compiler should be improved for the less efficient pattern, and not the user code.
Anyway, I think the decision what to use should be based on other criteria than the generated code.
Basically using bitfields has generates more readable C code.
There are also a couple of possible bugs when using masks which dont happen with the bitfield approach.
For example the code could use the bitmask for one register with the address of another one, or the & used in masking is common source of precedence bugs (I mean the "Reg & MAK == 0" type of bugs).
So the mask approach is often done with a bunch of macros, but that has its own drawbacks too.
The drawback of bitfields is that they are by the C language definition compiler dependent. If you use a header file delivered with the compiler, then that is not an issue, but if you want to program independent of the used compiler, then using bitfields is at least conceptually not an option.
BTW, using the mark you should use
Registername |= MASK_OF_BIT;
Registername &= ~MASK_OF_BIT;
Daniel