locked
StreamReader is too slow RRS feed

  • Question

  • I should send a command line to a controler and then read two line from the same controller. Code below should be sent every 20 or 10 ms (hope to be able to send every 5ms).
    testData = "0. 0. 0. \r\n";
    System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding ();
    byte[] bTest = encoding.GetBytes (testData);
    singleton.m_Socket.Send (bTest);
    theReader.ReadLine ();
    theReader.ReadLine ();

    But when i take a look at time used by the two last lines, it takes generaly less than a ms but 1/10 time, it takes more than 50 ms.

    I don't realy need to know what is read, I only need to delete data that came form my controller

    Wednesday, September 23, 2015 5:47 PM

Answers

  • I said 10 ms but in ideal case i'd like to send every 2 ms.
    Controller is only connected by ethernet, no drivers. I used it to control 3 motors like a CNC.
    It's the first time that i use ethernet projects and for my application, i decided to use C# and Unity engine. Until now, it was pretty simple to use.
    But now that i want to have better performance, it seems more difficult :(

    Performance issues once you get to realtime applications is the one big tradeoff of a garbage collected environment. Like Unity, C# and generally everything .NET Framework related. It's right there on wikipedia among the disadvantages of a Garbage Collector.

    http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29#Disadvantages

    Garbage Collection - Pros and Limits

    And the only way to avoid it is stop relying on it altogether and do the dangerous work of handling pointers and memory management directly. Basically what only driver, DB, OS and runtime programemrs do in the current day and age.
    If direct memory management is not fast enough nothing can be fast enough.

    Another issues might be that the OS clock is not nearly accurate enough for this. You will have to use something like a stopwatch class for timing below the 20 ms area:

    http://blogs.msdn.com/b/ericlippert/archive/2010/04/08/precision-and-accuracy-of-datetime.aspx

    Using Unity or .NEt Framework for this was propably a terrible design mistake if you are actually making a Realtime Application.

    • Proposed as answer by Kristin Xie Wednesday, October 7, 2015 9:02 AM
    • Marked as answer by Kristin Xie Thursday, October 8, 2015 3:14 AM
    Thursday, September 24, 2015 1:49 PM

All replies

  • What controler is it? How long are those "two lines"? Might be they are just are that long and hte controler is jsut that slow.

    As a general rule, you can never asume a minimum execution time for any code. The moment you get below 1000 ms between calls the best you can do is limit it to not run more often then every X ms. Rate limiting rather then timing.

    How about just calling ReadToEnd?

    Apparently Stream can't jsut skip lines natively, but it can be added in:

    http://stackoverflow.com/questions/4418319/c-sharp-how-to-skip-number-of-lines-while-reading-text-file-using-stream-reader


    Wednesday, September 23, 2015 6:00 PM
  • Have you checked timing with e.g WireShark?

    Also, remember that most operating systems nowadays have to give time to each process that is running. If you send the command and next your process has to give way for a few other ones, your read will be delayed.

    As far as I know you can give your process a highrr priority in Windows, but that will slow the other processes down and might make your system unresponsive.

    Wednesday, September 23, 2015 6:19 PM
  • Polling a controller every 10 ms is going to be difficult using managed code under Windows. If you are going to poll, then you should be using unmanaged code, namely C++.

    Better yet, tell us more about the controller. Does the manufacturer provide a driver? Can the the controller provide data through an interrupt-driven DeviceIOControl command?

    Wednesday, September 23, 2015 6:27 PM
  • I don't know exact lenght, but i know that it's always the same kind of data (string result) : it repeat datas sent and add a ">" symbol.
    It's curious cause it's only sometime that it takes more time....
    if i use read to end or read a third line, my software shut down.

    Wednesday, September 23, 2015 9:43 PM
  • I said 10 ms but in ideal case i'd like to send every 2 ms.
    Controller is only connected by ethernet, no drivers. I used it to control 3 motors like a CNC.
    It's the first time that i use ethernet projects and for my application, i decided to use C# and Unity engine. Until now, it was pretty simple to use.
    But now that i want to have better performance, it seems more difficult :(
    Wednesday, September 23, 2015 9:44 PM
  • Using a StreamReader will always cause allocations, which both cause garbage creation, and could be delayed by GC.  You may need to read the socket directly into a pre-allocated byte[].

    David


    David http://blogs.msdn.com/b/dbrowne/

    Wednesday, September 23, 2015 9:53 PM
  • I said 10 ms but in ideal case i'd like to send every 2 ms.
    Controller is only connected by ethernet, no drivers. I used it to control 3 motors like a CNC.
    It's the first time that i use ethernet projects and for my application, i decided to use C# and Unity engine. Until now, it was pretty simple to use.
    But now that i want to have better performance, it seems more difficult :(

    There is no way you will be able to reliably do this using .NET. You will have to set up a dedicated high-priority thread that polls every 2 ms. C++ is the way right tool for the job. If you like, use C++/CLI so that this module is callable from .NET, so the rest of your application can still be written in C#.
    Wednesday, September 23, 2015 10:26 PM
  • Did you have some quick links to help me to understand C++/CLI and how to use it with C# and .NET? I never used these techniques and I need to make it work pretty soon....
    Thanks

    Thursday, September 24, 2015 1:18 PM
  • I said 10 ms but in ideal case i'd like to send every 2 ms.
    Controller is only connected by ethernet, no drivers. I used it to control 3 motors like a CNC.
    It's the first time that i use ethernet projects and for my application, i decided to use C# and Unity engine. Until now, it was pretty simple to use.
    But now that i want to have better performance, it seems more difficult :(

    Performance issues once you get to realtime applications is the one big tradeoff of a garbage collected environment. Like Unity, C# and generally everything .NET Framework related. It's right there on wikipedia among the disadvantages of a Garbage Collector.

    http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29#Disadvantages

    Garbage Collection - Pros and Limits

    And the only way to avoid it is stop relying on it altogether and do the dangerous work of handling pointers and memory management directly. Basically what only driver, DB, OS and runtime programemrs do in the current day and age.
    If direct memory management is not fast enough nothing can be fast enough.

    Another issues might be that the OS clock is not nearly accurate enough for this. You will have to use something like a stopwatch class for timing below the 20 ms area:

    http://blogs.msdn.com/b/ericlippert/archive/2010/04/08/precision-and-accuracy-of-datetime.aspx

    Using Unity or .NEt Framework for this was propably a terrible design mistake if you are actually making a Realtime Application.

    • Proposed as answer by Kristin Xie Wednesday, October 7, 2015 9:02 AM
    • Marked as answer by Kristin Xie Thursday, October 8, 2015 3:14 AM
    Thursday, September 24, 2015 1:49 PM