Sorry, this is flat-out incorrect. Integer comparison uses hardware CMP instruction, which operates on data with the length equal to that of machine word. That means 32 bits on 32-bit computer. In fact, that's very easy to see for yourself.
Take the following code:
Code:
$ cat cmp.c
#include <stdio.h>
#include <inttypes.h>
int compare(int32_t i1, int32_t i2)
{
return i1 == i2;
}
int main(int argc, char **argv)
{
compare(1,2);
}
Compile (without optimization):
Code:
$ gcc -g -O0 cmp.c
$ gcc -g -O0 cmp.c -o cmp
And see the machine code of the compare() function:
Code:
$ gdb -q cmp
(gdb) set disassembly-flavor intel
(gdb) disass compare
Dump of assembler code for function compare:
0x080484c4 <compare+0>: push ebp
0x080484c5 <compare+1>: mov ebp,esp
0x080484c7 <compare+3>: mov eax,DWORD PTR [ebp+8]
0x080484ca <compare+6>: cmp eax,DWORD PTR [ebp+12]
0x080484cd <compare+9>: sete al
0x080484d0 <compare+12>: movzx eax,al
0x080484d3 <compare+15>: leave
0x080484d4 <compare+16>: ret
End of assembler dump.
The whole compare() function effectively compiles to two instructions (bolded). The first one MOVes the first (32-bit) variable from stack into the EAX register, while the second one CoMPares the EAX register with the second variable on stack.
If we now switch from 32-bit integers to 8-bit integers (i.e. change int32_t to int8_t), the function looks like that:
Code:
0x080484c4 <compare+0>: push ebp
0x080484c5 <compare+1>: mov ebp,esp
0x080484c7 <compare+3>: sub esp,0x4
0x080484ca <compare+6>: mov eax,DWORD PTR [ebp+8]
0x080484cd <compare+9>: mov edx,DWORD PTR [ebp+12]
0x080484d0 <compare+12>: mov BYTE PTR [ebp-1],al
0x080484d3 <compare+15>: mov BYTE PTR [ebp-2],dl
0x080484d6 <compare+18>: mov al,BYTE PTR [ebp-1]
0x080484d9 <compare+21>: cmp al,BYTE PTR [ebp-2]
0x080484dc <compare+24>: sete al
0x080484df <compare+27>: movzx eax,al
0x080484e2 <compare+30>: leave
0x080484e3 <compare+31>: ret
As you can see, there is no profit to be had, and even worse, there is a loss, because you can see the compiler doing two extra MOV's. (I am not sure why GCC is doing things that way, though. I'd simply cast both arguments to int32 and do a 32-bit hardware compare, resulting in a code identical to the first one).
Fun fact: optimized string compare functions actually use 32-bit compare to decrease the number of required CMP and MOV instructions by the factor of 4 (i.e. they compare 4 bytes each time instead of just one). See e.g.
http://www.opensource.apple.com/sour...n/ppc/memcmp.s
Code:
; int memcmp(const void *LHS, const void *RHS, size_t len);
;
; Memcmp returns the difference between the first two different bytes,
; or 0 if the two strings are equal. Because we compare a word at a
; time, this requires a little additional processing once we find a
; difference.
; r3 - LHS
; r4 - RHS
; r5 - len
Theoretically speaking, on a 64-bit machine, there should be no difference in performance between operating on 32-bit and 64-bit ints, because all operations will be done on 64-bit hardware registers anyway. On a 32-bit machine, operations on 64-bit ints will be slower than operations on (native) 32-bit ints, because 64-bit operations have to emulated by combining multiple 32-bit operations. (Any book on assembly language will have details).
There is however a fundamental difference in perfomance between using integer types and floating point types. As a general rule, integer operations are faster. By how much, depends on hardware.
Also, on a machine which has hardware support for floating point double precision numbers (meaning any processor with an FPU nowadays), there is no profit to be had from using single precision, because the compiler will cast the variable to double, do the calculations on hardware doubles, and truncate the result to single. So if anything, single will be slower because of extra casting required.