Thread: Optimise code (noob questions)

  1. #1
    Registered User
    Join Date
    Jun 2013
    Posts
    2

    Optimise code (noob questions)

    Hello, this is my first post

    I've done a simple file encryption program, but it takes too much cpu power and i will appreciate any advice you can give me to optimise my code. This is the part that needs to be improved:
    Code:
    while(1){ 
    
                err = fread( &byte_buff  , sizeof(unsigned char) , 1 , input_file );
    
                if( err != 1 ){                                    
                    if( feof( input_file ) ){                   
                        printf("\n\n Operation successful!\n");   
                        break;
                    }                                            
                    else{                                       
                        fprintf(stderr, "\n Error occured while reading from file!!!\n");
                        break;
                    }
                }
    
    
                //-- Encrypt / Decrypt the byte with Bitewise NOT
                byte_buff = ~ byte_buff;
    
                err = fwrite( &byte_buff  , sizeof(unsigned char) , 1 , output_file);
    
                if( err != 1 ){                                 
                    fprintf(stderr, "\n Error occured while writing!!!\n");
                    break;
                }
    
                if( (i % ( file_size / 20 ) == 0) && (i!=0) ){
                    printf("\b\b%d", percentage += 5); fflush(stdout);
                }
                i++;
                
            }
    Also i have a question about fread() and fwrite(). Is there a better way than read/write one byte at a time so i can boost the speed ? Because if i read more than 1 byte, lets say 2 but the file is 3 bytes, i'm not sure if fread() will read the last byte and when reach eof stop, or it will give me the last byte + 1 extra junk byte
    English is not my native language, so excuse me for my mistakes

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Dimebag
    it takes too much cpu power
    Did you measure the "cpu power"? I was expecting say, some complex encryption algorithm, but all you're doing for the encryption itself is applying bitwise not to unsigned chars.

    Quote Originally Posted by Dimebag
    Also i have a question about fread() and fwrite(). Is there a better way than read/write one byte at a time so i can boost the speed ?
    Notice that fread returns the number of bytes read, and that you can specify the number of bytes to write as an argument to fwrite.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Jun 2013
    Posts
    2
    I said it was simple , and the cpu usage is 25% which i think is too much for such program, thats my i wanted to know if i can optimise it

  4. #4
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    ^_^

    I don't know about the rest of you, but my money is on the original poster having a 4-core CPU and a "Windows" operating system.

    Soma

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    ^^^^ You're so cruel! I love it. ^^^^

    Dimebag, have you considered reading from the file, a block of chars at one time, and then encrypting/decrypting all of that block at once, before writing it to a file. Your logic feels like a roller coaster - I'm down reading a teeny little bit from a file, then I'm up en/de crypting, then I'm back down again writing a teeny little bit of data, to a file.

    I believe your intuition is right - go big with this, and ditch the read/do a tiny something/write, loop you have now.

    A profiler would be nice, here.

    You need SOME measurement of performance as it is now, so any changes can be compared on the same test data.

  6. #6
    Registered User migf1's Avatar
    Join Date
    May 2013
    Location
    Athens, Greece
    Posts
    385
    Welcome to the forum Dimebug.

    As Adak has already pointed out, it's much better if you work with blocks of bytes instead of one byte at a time. Ideally, if memory is no issue, you could even load the whole file in a buffer, encrypt/decrypt it and then write it back to disk.

    Here's a small function that returns the size of a file in bytes, as a long int (meaning it fails if there are more than LONG_MAX bytes in the file)...

    Code:
    long int f_size( const char *fname )
    {
        long int size;
        FILE     *fp;
    
        if ( NULL == (fp = fopen(fname, "rb")) )    /* binary mode */
            return -1;
    
        if ( 0 != fseek(fp, 0, SEEK_END) ) {
            fclose(fp);
            return -1;
        }
    
        size = ftell(fp);
        fclose(fp);
    
        return size;
    }
    * you may modify it to accept a FILE * pointer instead of a const char * filename, in an effort to avoid opening and closing the file inside the function.

    If the function fails (when for example the file is larger than LONG_MAX bytes) but you know that the file does exist, then you may fall back into reading the file gradually, via a buffer of predefined size.

    Or you could compare the return value of this function against the available memory and decide based on that the size of the buffer you will use.

    ftello() and ftello64() are non-portable alternatives for ftell(), although most compilers support at least the former as an extension.

    Note also that generally speaking, file I/O is performed much faster by using OS specific functions instead of generic ones.
    Last edited by migf1; 06-06-2013 at 06:59 AM. Reason: changed return value on failure from 0 to -1

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Knowing the file size in advance is pretty irrelevant IMO.

    All that attempting to load a large file into memory in one go will achieve would be the initial transfer of the entire file into memory, and then immediately to swap space, and then another transfer out of swap space back into memory.

    Standard C already declares BUFSIZ in stdio.h. Assuming your library implementer has done their job properly, this will be compatible with a basic storage unit of the file system such that I/O transfers are reasonably efficient.
    Code:
    char buff[BUFSIZ];
    while ( (n=fread(buff, sizeof(buff[0]), BUFSIZ, input_file)) > 0 ) {
      // do something with n bytes of data.
    }
    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.

  8. #8
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    The cpu time is being consumed by all the calls to fread() and fwrite() transferring 1 byte at a time. Try reading 65536 bytes to 1048576 bytes at a time. (You'll need to allocate a buffer that is the same size).

    Quote Originally Posted by Salem View Post
    All that attempting to load a large file into memory in one go will achieve would be the initial transfer of the entire file into memory, and then immediately to swap space, and then another transfer out of swap space back into memory.
    Unless the file size is 1GB or more, it seems unlikely that the file data in the programs memory would immediately end up in the swap space.

    Quote Originally Posted by Salem View Post
    Standard C already declares BUFSIZ in stdio.h.
    For a PC (at least with visual studio), BUFSIZ is defined to be 512 bytes, the size of a sector. If the actual file I/O (reads and writes) are done 512 bytes at a time, that's fairly inefficient. Most PC's have 4GB or more of ram, and even with a 32 bit system, a program can usually allocate 1GB of ram without issues.

  9. #9
    Registered User migf1's Avatar
    Join Date
    May 2013
    Location
    Athens, Greece
    Posts
    385
    @Salem: Good point!

    Actually the OS and even the hd will take care of buffering, caching, etc (I think the library is free to implement fread()/fwrite() anyway it likes, as long as it is buffered) .

    However, if most of the files are reasonable sized then swapping is much less probable to happen anyway. Also, the less calls to fread()/fwrite() the less probable I/O blocking overhead will take place.

    All in all, a profiler (along with enough test cases) should be used for safe conclusions, before applying either approach. Also, setvbuf() can also be used for optimization experiments, etc. Knowing before hand the size of the file to be handled, is often a plus for an educated decision.

    There's no easy way to vote for one or the other, without testing first on the specific platform, for the specific dataset and for the specific application.

  10. #10
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Just reading 4096 bytes at a time would be good enough. Reading one byte at a time is beyond awful, for performance.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help me optimise my code!
    By AmbliKai in forum C Programming
    Replies: 16
    Last Post: 10-15-2008, 11:33 AM
  2. Few more noob questions
    By SlpCtrl in forum C Programming
    Replies: 12
    Last Post: 10-14-2008, 04:32 PM
  3. 2 very noob questions
    By chasingxsuns in forum C Programming
    Replies: 20
    Last Post: 05-07-2006, 11:04 PM
  4. Noob Questions...
    By Firemagic in forum C++ Programming
    Replies: 4
    Last Post: 04-19-2006, 03:57 PM
  5. Will 'static' optimise my code?
    By samGwilliam in forum C++ Programming
    Replies: 3
    Last Post: 03-29-2005, 11:28 AM

Tags for this Thread