Thread: Is there a standard function?

  1. #76
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    x64 or x86?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  2. #77
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    45 seconds on 64, 36 seconds (!) on 32.

  3. #78
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Weird. It's probably attributed to the use of a specific compiler.
    Or perhaps it's the cpu?

    The value of num is: -123456

    init_time = 1278269704

    The formatted value of num is: -123,456

    end_time = 1278269714


    The routine test has taken about 10 seconds

    to perform 500,000,000 cycles of the formatting function
    Press any key to continue . . .

    EDIT: My binary: Filebeam - Beam up that File Scottie!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #79
    Registered User
    Join Date
    Jun 2010
    Posts
    182
    Quote Originally Posted by cyberfish View Post
    Well, the reason all modern compilers ignore the keyword is because they can all make better decisions than people who think they can .

    If the optimized version runs 30 times slower than GCC's, I would be worried.


    Maybe. Certainly not 30 times better, though .

    32-bit mode takes 2 seconds for me.
    So far it's never happened that a compiler was smarter than me regarding
    the matter of choosing a register :-)

    I always test the program with and without the register keyword.
    This case is not an exception, with the register keyword it runs faster
    than without, on my pc.

    The real problem is CPU + 64/32 bit mode + OS + Compiler.

    Probably the combinations you are using are better than the one I am.
    I have tried Elysia version, and it is much slower than mine on my pc.
    By the way the test should be done with the number -1234567890 like
    the one I'm using now to be relevant.

    I'm going to install a Win port of GCC, just to verify if and to what extend it
    depends on the compiler, even if I doubt a lot about that.

    My pc is a Core Duo, 32 bit, but with Win / 64 bit installed.

  5. #80
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    Can you post the exact version you are running so we can all run the same thing?

  6. #81
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by frktons View Post
    So far it's never happened that a compiler was smarter than me regarding
    the matter of choosing a register :-)

    I always test the program with and without the register keyword.
    This case is not an exception, with the register keyword it runs faster
    than without, on my pc.
    Try that with VC++/GCC. It will likely not matter one bit.

    I've put a link to my binary. It's the same source I posted compiled with Visual Studio 2010 (as C++ code, though; though I don't think that matters).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #82
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    By the way, what's the difference between
    Code:
    for (x = 0; x < 14; x++)
    	{
    		if (buffer[x] == '+' || buffer[x] == '-' || buffer[x] == sep || buffer[x] >= '0' && buffer[x] <= '9')
    			printf("%c",buffer[x]);	
    		if (buffer[x] == '\0')
    			break;
    	}
    and
    Code:
    printf("%s", buffer);
    ?

  8. #83
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    And I believe in Elysia's version,
    Code:
    int len_str = (int)log10((double)num);
    This is the bottleneck.

    The casting is very expensive (from integral to IEEE double), and log10(double) is also very expensive. A binary search loop would be much faster. Or linear search if number of digits is small.

  9. #84
    Registered User
    Join Date
    Jun 2010
    Posts
    182
    The version I'm using is:
    Code:
    // ----------------------------------------------------------------------------------------------
    // Prog_name: comma_sep.c / ver 0.5
    // A routine for formatting integer numbers with thousand separators. 
    // Created with Pelles C for Windows 6.00.4
    //-----------------------------------------------------------------------------------------------
    // This version takes into account the sign and the possibility to have different
    // separator like space, comma, point, and so on. 
    // Moveover this version creates a function that can be tested for performance. 
    // Added the choice for right and left alignment.
    // In this version Global variables have been removed.
    //-----------------------------------------------------------------------------------------------
    // Date: 04 july 2010
    // Author: frktons @ cprogramming forum.
    //-----------------------------------------------------------------------------------------------
    
    #include <stdio.h>
    #include <stdbool.h>
    #include <time.h>
    #undef getchar
    #pragma comment(lib, "\\masm32\\lib\\msvcrt.lib")
    
    
    
    //-----------------------------------------------------------------------------------------------
    // Function prototype for int_format(). Takes the number to format,
    // the address of the string to fill, some switches and thousand separator. 
    // Returns nothing.
    //-----------------------------------------------------------------------------------------------
    
    void int_format(int num, char *, bool sign, bool neg, char sep, char alignment);
    
    //-----------------------------------------------------------------------------------------------
    
    int main(int argc, char *argv[])
    {
    
    //-----------------------------------------------------------------------------------------------
    // Local variables. 
    //-----------------------------------------------------------------------------------------------
        bool sign = true;              // if the number has to be displayed with sign
        bool neg = false;              // if the number is negative this flag will be set
                                                  // from the function to reflect the state
    
        char sep = ',';                   // here I choose the separator 
        char buffer[15] = {' '};        // string array for the formatted number
        char alignment = ' ';         // choice to [R]ight-align or [L]eft-align the number   
        int num = -1234567890;           // test number
        int cycles = 0;
        float ver = 0.5;                   // Program version
    
    
        int x;                                  // generic integer counter
        time_t init_time = 0;          // initial time
        time_t end_time = 0;        // end time 
        alignment = 'L';               // the formatted number will be Left-aligned
     
        int times = 500000000;      // for testing performance set this number for repetitions
    
        printf("\n\t\t\t Testing version : %.2f \n",ver);
       printf("\n\t\t\t ----------------------\n");
        printf("\n The value of num is: %d\n",num);
    
        time(&init_time);
    
        printf("\n init_time = %d \n",init_time);    
    
        for (cycles = 0; cycles < times; cycles++) {
            for (x=0; x < 14; x++)
                buffer[x] = ' '; 
            int_format(num, buffer, sign, neg, sep, alignment);
        } // end for
        
        printf("\n The formatted value of num is: ");
        for (x = 0; x < 14; x++)
        {
            if (buffer[x] == '+' || buffer[x] == '-' || buffer[x] == sep || buffer[x] >= '0' && buffer[x] <= '9')
               printf("%c",buffer[x]);	
            else if (buffer[x] == '\0')
               break;
        }
        printf("\n\n");
        time(&end_time);
        printf(" end_time  = %d \n",end_time);    
    
        printf("\n\n The routine test has taken about %d seconds\n", end_time - init_time);
        for (x=0; x < 14; x++)
            buffer[x] = ' '; 
    //    buffer[14] = '\0';
        neg = false;
        sign = false;
        int_format(times, buffer, sign, neg, sep, alignment);
        printf("\n to perform ");
        for (x = 0; x < 14; x++)
        {
            if (buffer[x] == '+' || buffer[x] == '-' || buffer[x] == sep || buffer[x] >= '0' && buffer[x] <= '9')
               printf("%c",buffer[x]);	
            else if (buffer[x] == '\0')
               break;
        }	
        printf(" cycles of the formatting function");
        getchar();
        return 0;
    }
    //--------------------------------------------------------------------------------------------------------------------
    // Function int_format()
    //--------------------------------------------------------------------------------------------------------------------
    
    void   int_format(int number, char *buffer, bool sign, bool neg, char sep, char alignment){
    
        register int num = number;
        int x = 0;
        int y = 0;
        const int ten = 10;
        register int remain = 0;    // integer variable to store the remainder
        int count = 0;                    // integer counter for positioning the separator  
        bool zero = false;             // if the number is zero the function sets this
                                                  // flag for its decisions
        char digit[10] = {'0','1','2','3','4','5','6','7','8','9'};   // the digits to display in char shape 
        int len_str = 14;                 // string lenght less the terminator NULL
    
        if (num != 0) 
        {
            if (num < 0)
            {
                neg = true;
                num = num * -1 ; // transform number to positive if negative
            }
            for (x = len_str; x >= 0; x--)
             {
                if (num == 0) 
                    break;
                if (count == 3)
    	   {
    	       count = 0;
    	       buffer[x] = sep;
    	       x--;
                }
    
                remain = num % ten;
                num = num / ten;
                buffer[x] = digit[remain];
    //            buffer[x] = '0' + remain;
                count++;
              }  
        }
        else
        {
            buffer[len_str] = '0';
            zero = true;
        }
    
        if (sign == true && neg == true)
            buffer[x] = '-';
        else if (sign == true && zero == false)
            buffer[x] = '+';
    
         if  (alignment  == 'L') {
             if (x == 0)
    	     return;
             for (y = 0; y < 15; y++, x++) {
                 buffer[y] = buffer[x];
                 if (buffer[y] == '\0')
    	         return;
             } // end for
    
         }
    
        return;
    
    }
    and the output is:
    Code:
                             Testing version : 0.50
    
                             ----------------------
    
     The value of num is: -1234567890
    
     init_time = 1278270428
    
     The formatted value of num is: -1,234,567,890
    
     end_time  = 1278270501
    
    
     The routine test has taken about 73 seconds
    
     to perform 500,000,000 cycles of the formatting function

  10. #85
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Funny, when I used -123456 on my system, it took 9 seconds to run with:

    gcc -Wall -Wextra -o speed speed.c

    When I did -O3, it took 1 second to run it.

    When I changed the number to -1234567890, it took 14 seconds to run with:

    gcc -Wall -Wextra -o speed speed.c

    And zero seconds with the -O3 switch.

    My system:

    gcc version 4.4.1

    Linux 2.6.31

    AMD Athlon II X2 250 (3.0GHz)

    I wish I had more time so I could run some tests on OpenSolaris with Sun's C compiler....

  11. #86
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    Code:
    			 Testing version : 0.50 
    
    			 ----------------------
    
     The value of num is: -1234567890
    
     init_time = 1278270636 
    
     The formatted value of num is: -1,234,567,890
    
     end_time  = 1278270641 
    
    
     The routine test has taken about 5 seconds
    
     to perform 500,000,000 cycles of the formatting function
    Time to switch compiler I think .

  12. #87
    Registered User
    Join Date
    Jun 2010
    Posts
    182
    Quote Originally Posted by cyberfish View Post
    Code:
    			 Testing version : 0.50 
    
    			 ----------------------
    
     The value of num is: -1234567890
    
     init_time = 1278270636 
    
     The formatted value of num is: -1,234,567,890
    
     end_time  = 1278270641 
    
    
     The routine test has taken about 5 seconds
    
     to perform 500,000,000 cycles of the formatting function
    Time to switch compiler I think .
    Time to tell me the HW/SW configuration you are using as well. :-)

    Quote Originally Posted by cyberfish View Post
    By the way, what's the difference between
    Code:
    for (x = 0; x < 14; x++)
    	{
    		if (buffer[x] == '+' || buffer[x] == '-' || buffer[x] == sep || buffer[x] >= '0' && buffer[x] <= '9')
    			printf("%c",buffer[x]);	
    		if (buffer[x] == '\0')
    			break;
    	}
    and
    Code:
    printf("%s", buffer);
    ?
    Just for fun, no difference at all. :-)
    Last edited by frktons; 07-04-2010 at 01:16 PM.

  13. #88
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by cyberfish View Post
    By the way, what's the difference between
    Code:
    for (x = 0; x < 14; x++)
    	{
    		if (buffer[x] == '+' || buffer[x] == '-' || buffer[x] == sep || buffer[x] >= '0' && buffer[x] <= '9')
    			printf("%c",buffer[x]);	
    		if (buffer[x] == '\0')
    			break;
    	}
    and
    Code:
    printf("%s", buffer);
    ?
    Dude, I have no idea. Not my code.
    Also, I think I have found the reason for the speedup.
    For some reason, VC++ is able to inline int_format on x64. Indeed, this provides the speedup. Disabling it ramps the time up to 29 seconds.
    This is not done in x86, though. Why, I don't know, but there you have it.

    Quote Originally Posted by cyberfish View Post
    And I believe in Elysia's version,
    Code:
    int len_str = (int)log10((double)num);
    This is the bottleneck.

    The casting is very expensive (from integral to IEEE double), and log10(double) is also very expensive. A binary search loop would be much faster. Or linear search if number of digits is small.
    True. It does take a lot of time, I've noticed.
    The question is how to optimize that. I threw off a couple of suggestions before, but I haven't tried anything.
    Last edited by Elysia; 07-04-2010 at 01:15 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #89
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    Time to tell me the HW/SW configuration you are using as well. :-)
    Core 2 Duo at 3GHz, 64-bit Linux, GCC 4.4.1.

    Un-optimized version runs in 150 seconds, so your compiler is most certainly optimizing, just not nearly as much.

    Dude, I have no idea. Not my code.
    Yeah I was talking to frktons.

  15. #90
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I've managed to cut 10 seconds by getting rid of log10. Horribly slow function, that. Regular division is faster. Unfortunately, now the compiler refuses to inline the function
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Change this program so it uses function??
    By stormfront in forum C Programming
    Replies: 8
    Last Post: 11-01-2005, 08:55 AM
  3. const at the end of a sub routine?
    By Kleid-0 in forum C++ Programming
    Replies: 14
    Last Post: 10-23-2005, 06:44 PM
  4. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM
  5. Replies: 5
    Last Post: 02-08-2003, 07:42 PM