One approach is to look at the assembly listing of the program.
After compiling the program (via the Verify or Download button) locate the directory where the .cpp, .hex, and .elf files for the program have been stored. (If you have trouble finding them, briefly turn on verbose compile options in the arduino IDE and look at the directory names in the output.)
In that directory, run
avr-objdump -S fn.cpp.elf
> listing.txt where fn.cpp.elf is the name of your sketch with
.ino taken off and
.cpp.elf added on at the end. For example, with sketch
avr-objdump -S serialecho.cpp.elf > listing.txt
listing.txt file, and subtract each function's starting address from its ending address, using hex arithmetic. For example, with
in the listing we will see
...(6 lines snipped)...
144: 26 e0 ldi r18, 0x06 ; 6
146: 40 e8 ldi r20, 0x80 ; 128
148: 55 e2 ldi r21, 0x25 ; 37
14a: 60 e0 ldi r22, 0x00 ; 0
14c: 70 e0 ldi r23, 0x00 ; 0
14e: 80 e1 ldi r24, 0x10 ; 16
150: 92 e0 ldi r25, 0x02 ; 2
152: db c1 rjmp .+950 ; 0x50a <_ZN14HardwareSerial5beginEmh>
The calculation 0x154–0x144 = 0x10 shows this portion of
setup is 16 bytes long.
These examples were generated on a linux system. I think the approach is the same on a MSWindows system except you may need to say
avr-objdump.exe instead of
avr-objdump, and may need to specify its path. See, eg, the Assemler results, where? thread at forum.arduino.cc.