Thread: code size

  1. #1
    Registered User
    Join Date
    Jan 2007
    Posts
    330

    code size

    suppose I have the following code occurring at 2000 spots in a program

    Code:
    printf("hello\n");
    I imagine every time that printf is called some assembly is generated to perform this function.
    Let's say it's 4 instructions to push, save registers and call printf.

    What if I make a function like

    Code:
    void print(void) { printf("hello\n"); }
    and put print() calls at 2000 spots in my program therefore hiding the 4 instructions inside print and just use 1 instruction to get to the 4 instructions.

    Would this be better in terms of code size or cant I say anything in general about technique like this?

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    Well, I tried making two programs using gcc in Linux, one with 2048 copies of the printf() and one with 2048 copies of the print(), and the print() version is about half the size (about 27k vs. 13k respectively). The difference is roughly the size of 2048 copies of the string "hello\n".

  3. #3
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Even smaller: puts("hello");

  4. #4
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Something of assembly call to printf():

    Code:
    push offset hellomsg
    call _printf
    add esp, 4
    Code to call your function print() that calls printf:

    Code:
    call _print
    add esp, 4
    To call a function takes about one or two assembly statements, not counting passing parameters. This means calling your print() function adds some overhead in the amount of assembly code generated.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > The difference is roughly the size of 2048 copies of the string "hello\n"
    Examine the executable, there should only be one copy of the string, since most compilers nowadays merge duplicate strings.

    > Would this be better in terms of code size or cant I say anything in general about technique like this?
    Well a function call to a function containing only one line is always going to be marginal in terms of it's effects on code size.
    But yes, identifiing blocks of repeated code (or different blocks which can be parameterised) will make for shorter code.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    > Examine the executable, there should only be one copy of the string, since most compilers nowadays merge duplicate strings.

    Yes, you're correct.

  7. #7
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Of course he's correct its Salem, AKA God of the C

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    > Even smaller: puts("hello");

    Actually, the output of the "strings" command, which is exactly the same for both versions, includes puts, but not printf, so this is optimized already (probably to get rid of the extra \n). If I delete the \n in one of the strings in the first version, the output includes both printf and puts.

    /lib/ld-linux.so.2
    __gmon_start__
    libc.so.6
    _IO_stdin_used
    puts
    __libc_start_main
    GLIBC_2.0
    PTRh
    QVhT
    [^_]
    hello

  9. #9
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by KIBO View Post
    and put print() calls at 2000 spots in my program therefore hiding the 4 instructions inside print and just use 1 instruction to get to the 4 instructions.
    Not necessarily. Most ABI conventions (the specification of how machine features are used by compiled languages to implement calling conventions, among other things) provide that certain sets of registers are reserved, and some are volatile across function calls. This means, especially in the case of optimized code, certain registers may be used that might be destroyed by the called function. These registers must be preserved on the stack and restored after the function call.

    So just because a function takes no arguments does NOT imply that nothing is pushed on the stack when it is called. It is far more useful to assume that each function call has a fixed overhead.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Trouble with DMA Segmentation Faults
    By firestorm717 in forum C Programming
    Replies: 2
    Last Post: 05-07-2006, 09:20 PM
  2. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  3. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  4. Replies: 11
    Last Post: 03-25-2003, 05:13 PM
  5. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM