Not because of C; that's for sure. The two biggest reasons are:
1) Your Commodore 64 is doing at least a couple orders of magnitude less actual work. This has less to do with language choice than it does with a programmer who is fully in touch with the problem to be solved and can identify unnecessary work to eliminate.
2) Your Commodore 64 is effectively designed in a way that prioritizes latency over throughput. Pipelines and buffers are small-to-nonexistent. When you read the joystick port, you sample the state of that joystick at that very microsecond; you're not asking one microcontroller to ask another microcontroller to start thinking about sending the input it sampled 10 milliseconds ago. The worst-case latency from changing the video data to seeing it on screen is measured in lines, not frames (assuming a low-latency display like a dumb CRT). Virtually nothing is asynchronous. Systems aren't built that way anymore because we want to be able to push massive amounts of data through subsystems that can't all run in lockstep to one fast master clock, and that means lots of buffering and burst transfers.