int
is usually the fastest all-round type. This property isn't mandated by the standard, but it's usually the case for today's platforms. We've also got things like cstdint's int_fast32_t
which is more properly guaranteed to be the fastest type that can hold at least 32 bits -- highly recommend them for perf-sensitive code!
size_t
isn't intended to give a fast integer. Its purpose is to provide an integer that can hold the size of the largest sized object your platform's address space can contain. Typically size_t
is equivalent to the largest "native" integer your CPU supports, but it doesn't have to be.
I'm going to guess that you're on a 64-bit platform. Generally a 64-bit platform has about equal perf for 32-bit and 64-bit ops, but you've hit the one place they typically aren't: div/mod can actually be 2-3x slower on a 64-bit integer. In this case if int
is 32-bit and size_t
is 64-bit, it explains the issue nicely.
See Agner Fog's instruction tables document for more info. For Intel's Sandy Bridge platform, it shows 32-bit div has a latency of 20-28 cycles while 64-bit div takes 30-94 cycles.