Thread: Why is this program so slow in Windows

  1. #1
    C lover
    Join Date
    Oct 2007
    Location
    Virginia
    Posts
    266

    Why is this program so slow in Windows

    I wrote a simple port scanner that is dog slow in Windows (Had to make some modifications for it to work under Windows obviously but it's working. Under a Linux distro it's lightning fast:

    Code:
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #define PORT_MIN 0x0000
    #define PORT_MAX 0xFFFF
    
    #pragma comment(lib, "ws2_32.lib")
    
    void test_port(SOCKET, struct sockaddr_in *, unsigned short, char *);
    void print_port();
    
    int main(int argc, char ** argv){
    
        SOCKET client_socket;
        WSADATA wsaData;
        struct sockaddr_in target;
        unsigned short port = PORT_MIN;
    
        WSAStartup(MAKEWORD(2, 2), &wsaData);
    
        memset(&target, sizeof(target), 0);
    
        if((target.sin_addr.s_addr = inet_addr(argv[1])) != INADDR_NONE)
            while(port++ < PORT_MAX)
                test_port(client_socket, &target, port, "tcp");
    
    
    
        return 0;
    }
    
    void test_port(SOCKET client_socket, struct sockaddr_in * target, unsigned short port, char * svc_proto){
    
        struct servent * service;
    
        printf("Testing %s port %u\r", svc_proto, port);
    
        target->sin_family = AF_INET;
        target->sin_port = htons(port);
    
        if((client_socket = socket(AF_INET, SOCK_STREAM, 0)) != INVALID_SOCKET)
            if(connect(client_socket, (struct sockaddr *)target, sizeof(*target)) != SOCKET_ERROR){
                closesocket(client_socket);
                if(service = getservbyport(port, svc_proto))
                    printf("Discovered open port %u (%s)/%s\n", port, service->s_name, svc_proto);
                else
                    printf("Discovered open port %u/%s\n", port, svc_proto);
            }
    
    }

  2. #2
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    This is a case where you might be better off asking about this issue at msdn forums. There are some people there that are familiar with the internal workings of windows, which should be helpful.

  3. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Because Microsoft want it to be slow. "Port scanning" is not generally regarded as a necessary feature of non-malicious programs.
    There are limits on the number of half-open connections hard-coded into XPSP2 and everything that came after it IIRC. This places a massive restriction on the speed at which this can operate.
    I suggest you just forget trying to port it to Windows. I'm prety sure you will not get it fast.
    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"

  4. #4
    Registered User ledow's Avatar
    Join Date
    Dec 2011
    Posts
    435
    Yes, basically, Windows limits this for "security" purposes. There are settings in the registry to relax it a little but generally, since Windows XP, you have to edit core DLL files on Windows to increase the number of connections you can make from a program. Every user running your program would have to replace a core Windows file to run that at any sort of decent speed.

    The workaround for similar programs is to use the WinPCap interfaces which allow some more arbitrary access to the network itself but that's a lot more complex than just opening a socket or two. However, that needs your users to install the WinPCap driver with admin access, and you to convert all your code to pcap-capable networking code. Generally, the hassle isn't worth it unless you're writing something like nmap and, why bother? Nmap is already written for you (and uses WinPCap).

    Linux is an industrial tooling factory. If you have access to a particular room in it, then it might have a warning here and there, but it generally assumes that you won't put yourself in the middle of the machinery and pull the lever that would crush you (or others). If you don't have access to those rooms, then you can't do anything in them.

    Windows is a crèche. Everything is baby-proofed and you can't (supposedly) hurt yourself. You're not deemed important enough to override MS's chosen security settings without a lot of hassle or complete admin access.

    And, to be honest, outside of "educational" use, there's really no reason to be port-scanning anything anyway. Use the tools provided to do that, if you're an admin and require it, or don't do it at all.

    You're outside the realm of basic C programming and into the realm of network security, quotas, limits, DDoS, and everything else.

    - Compiler warnings are like "Bridge Out Ahead" warnings. DON'T just ignore them.
    - A compiler error is something SO stupid that the compiler genuinely can't carry on with its job. A compiler warning is the compiler saying "Well, that's bloody stupid but if you WANT to ignore me..." and carrying on.
    - The best debugging tool in the world is a bunch of printf()'s for everything important around the bits you think might be wrong.

  5. #5
    C lover
    Join Date
    Oct 2007
    Location
    Virginia
    Posts
    266
    Thanks for taking the time to respond guys. I'm not trying to do anything malicious, I simply was looking through the sockets API book that I have and thought to myself (I bet I could write a port scanner with the knowledge I have). Lo and behold, it was way easier (For TCP port checking anyways) than I thought to write one. It's a project for fun, just to see if I could do it. I know about NMAP.

  6. #6
    Registered User
    Join Date
    Mar 2012
    Location
    the c - side
    Posts
    373
    There may be other reasons as well.

    I use Linux and Windows and a few months back I was regularly running the same c programs on the same computer but different OS at different times. I noticed that in programs that involved loops with a large number of iterations, the performance in Linux was much faster than Windows

    I've just run the code below on both systems (32 - bit ), just to check again.

    The results were:

    Windows XP - 16.623 secs
    Puppy Linux - 0.2 secs

    Any explanations for the performance difference?

    Code:
    #include <stdio.h>
    #include <time.h>
    
    #define LIMIT 0x10000
    
    int main(void)
    {
        int index;
        time_t start,finish;
        double time;
    
        start = clock();
    
        for(index = 0;index < LIMIT;index++)
        {
            printf("Index = %d\n",index);
        }
    
        finish = clock();
    
        time = ((double)finish - start)/CLOCKS_PER_SEC;
    
        printf("Program Time = %lf\n",time);
    
        return 0;
    }

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    There could be tremendous differences, they all depend on the hardware in the machines and how you compiled; there is also the possibility that the clock readings you are getting are wholly inaccurate. Time.h is not a high-resolution clock library that you can use to find out how long your program is really taking etc. it is there to tell time the same way Big Ben does. When you are counting processor cycles, you do not want the time expressed in a manner of seconds from January 1, 1970. Use a code profiler if you just want to find out how long something takes in relation to other things, or use a hardware timer if you really need a number.

  8. #8
    Registered User ledow's Avatar
    Join Date
    Dec 2011
    Posts
    435
    Too many reasons that have nothing to do with the OS performance as much as the C standards, multitasking OS's, display speed for printf(), etc. and just basic variability that you haven't accounted for.

    Windows 7 (first run, immediately after compile): 0.570000
    Windows 7 (third run, immediately running one after another after another): 0.173000

    CLOCKS_PER_SEC might vary, clock() isn't accurate, OS's don't assign the same processor priority to user processes (which user did you run as?), Linux text consoles are optimised to do printf()-type output, GUI's aren't (and GUI performance may be dependent on video card, drivers or even hardware and accelerations available), disk caching may not be the same (which is the cause of my differing results above), etc. etc. etc.

    Don't benchmark things until you know how to. Primitive benchmarks are useful only as an indicator. And, the fact is, we're talking about network actions mainly, which are in a very, very different realm to just printing some integers to the console.

    - Compiler warnings are like "Bridge Out Ahead" warnings. DON'T just ignore them.
    - A compiler error is something SO stupid that the compiler genuinely can't carry on with its job. A compiler warning is the compiler saying "Well, that's bloody stupid but if you WANT to ignore me..." and carrying on.
    - The best debugging tool in the world is a bunch of printf()'s for everything important around the bits you think might be wrong.

  9. #9
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    That example depends entirely upon the buffering behaviour and efficiency of printf in the runtime library you are using. That's nothing to do with the OS.
    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"

  10. #10
    Registered User
    Join Date
    Mar 2012
    Location
    the c - side
    Posts
    373
    Points taken.

    I was using gcc on both systems in virtual consoles i.e. multitasking enviroments.
    Also agree my timing program is pretty scrappy,just thought it was better than
    a hearsay statement of "Linux was faster".

    The timing differences may not be completely accurate but reflect well the large
    difference in performance.As you can appreciate the experience of one program
    running for less than a second and another running for well over ten seconds is
    pretty obvious without timing.

    And given that the Ops program has at its core essentially the same loop, does it
    not make sense that they may be runnning into this same performance issue?

  11. #11
    Registered User
    Join Date
    May 2012
    Posts
    505
    Quote Originally Posted by gemera View Post
    There may be other reasons as well.

    I use Linux and Windows and a few months back I was regularly running the same c programs on the same computer but different OS at different times. I noticed that in programs that involved loops with a large number of iterations, the performance in Linux was much faster than Windows

    I've just run the code below on both systems (32 - bit ), just to check again.

    The results were:

    Windows XP - 16.623 secs
    Puppy Linux - 0.2 secs

    Any explanations for the performance difference?

    Code:
    #include <stdio.h>
    #include <time.h>
    
    #define LIMIT 0x10000
    
    int main(void)
    {
        int index;
        time_t start,finish;
        double time;
    
        start = clock();
    
        for(index = 0;index < LIMIT;index++)
        {
            printf("Index = %d\n",index);
        }
    
        finish = clock();
    
        time = ((double)finish - start)/CLOCKS_PER_SEC;
    
        printf("Program Time = %lf\n",time);
    
        return 0;
    }
    You're picking up the difference in the consoles.
    The Linux console is designed to run C programs which produce voluminous output, so it has good buffering and update capabilities. The Windows console is designed mainly to run legacy DOS applications, so it's meant only to print out a few lines interactively, and you are stressing it if you try to pass it massive text dumps.
    I'm the author of MiniBasic: How to write a script interpreter and Basic Algorithms
    Visit my website for lots of associated C programming resources.
    https://github.com/MalcolmMcLean


  12. #12
    Registered User
    Join Date
    Mar 2012
    Location
    the c - side
    Posts
    373
    Ok, that makes sense.

    Clearly then this is a major performance issue for the OP program which appears to be a typical Windows console program.

  13. #13
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Couldn't the original posted program be modified to output the results to a text file instead of using printf in order to avoid performance differences in the console interface? The output could be redirected to a text file, but I'm not sure what effect '\r' will have on text file output.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why is my program so slow?
    By Canucklehead in forum C++ Programming
    Replies: 2
    Last Post: 10-17-2005, 05:45 AM
  2. Slow windows
    By somesh_chan in forum Tech Board
    Replies: 6
    Last Post: 10-03-2004, 11:13 AM
  3. Program is slow. Help
    By jjj93421 in forum C++ Programming
    Replies: 14
    Last Post: 08-08-2004, 07:39 AM
  4. This program makes my computer SLOW
    By Granger9 in forum C Programming
    Replies: 5
    Last Post: 10-15-2002, 01:18 AM
  5. Replies: 6
    Last Post: 01-07-2002, 02:46 AM