XOR CX, CX ;0x31 0xC9
Only two bytes are used: opcode 0x31 and the ModR / M byte, which stores the source and destination registers (in this case, the two are the same).
MOV CX, 0 ;0xB8 0x08 0x00 0x00
More bytes are required: opcode 0xB8 , ModR / M for the destination (in this case, CX), and two bytes that are immediately filled with zeros. There is no difference with the prospect of synchronization (both take only one clock cycle), but mov requires 4 bytes, and xor only two.
OR AX, AX ;0x0A 0xC0
again uses only operation bytes and ModRM bytes, and
CMP AX, 0 ;0x3D 0x00 0x00 <-- but usually 0x3B ModRM 0x00 0x00
uses three or four bytes. In this case, it uses three bytes ( 0x3D , the word immediate represents zero), since x86 has special opcodes for some operations with the Accumulator register, but usually it will use four bytes (opcode, ModR / M, word immediate). This is again the same when it comes to processor clock cycles.
There is no difference in processor performance
AND AL, 0x0F ;0x24 0x0F <-- again special opcode for Accumulator
and
SUB AL, '0' ;0x2D 0x30 0x00 <-- again special opcode for Accumulator
(only one byte difference), but when you subtract ASCII zero, you cannot be sure that there will be no value greater than 9 left in Accumulator. Also adding the OF and CF sets to zero, and sub sets them according to the AND ing result may be safer, but my personal opinion is that this use depends on the context.