简体   繁体   中英

How can I increase the number of concurrent async calls?

I am trying to increase the number of concurrent async calls I can make in C#. Specifically, I am trying to match the performance I'm seeing in Node.js.

Below are two sample programs, one in C# and one in JavaScript. The both read a random number of bytes into a buffer from a 10MB file containing random numbers, then execute this operation 2000 times asynchronously. The JavaScript program can do this about 60,000 times per second on my machine, but the C# program can only do about 3,000. As far as I can tell, they are doing the same thing, but I realize there are definitely some differences.

I have run similar tests with different functions, including sleeping for a small amount of time, and performing inserts to a Cassandra cluster using the Datastax Cassandra drivers. The latter functionality is what I'm really trying to improve, as I can only get about 80 inserts per second in C#, but about 5000 in Node.

Can someone help me explain this discrepancy?

// C#

class Program
{
    static Random r = new Random();

    static void Main(string[] args)
    {
        int iterations = 2000;

        Stopwatch s = new Stopwatch();
        s.Start();

        var tasks = Enumerable.Range(1, iterations).Select(i => ReadFile()).ToArray();
        Task.WaitAll(tasks);

        s.Stop();

        Console.WriteLine("Total elapsed milliseconds was {0}.", s.ElapsedMilliseconds);
        Console.WriteLine("Total iterations were {0}.", iterations);
        Console.WriteLine("Total iterations per second was {0}.", iterations / s.Elapsed.TotalSeconds);
    }

    static async Task ReadFile()
    {
        string path = @"C:\Temp\random.txt";
        int readSize = r.Next(512, 10 * 1024);

        using (StreamReader reader = new StreamReader(path))
        {
            await reader.ReadAsync(new char[readSize], 0, readSize);
        }
    }
}

// JavaScript

var fs = require('fs');
var now = require('performance-now');

var iterations = 2000;
var startTime = now();
var runningIterations = 0;

for (var i = 1; i <= iterations; i++) {
    readFile(function () {
        runningIterations++;

        if (iterations == runningIterations) {
            totalTime = (now() - startTime);
            console.log("Total iterations: " + iterations);
            console.log("Total time: " + totalTime);
            console.log("Iterations per second: " + (iterations / (totalTime / 1000)));
        }
    });
}

function readFile(callback) {
    var path = "/Temp/random.txt";

    fs.open(path, 'r', function (err, fd) {
        var readSize = Math.floor(Math.random() * 10 * 1024) + 512;
        var buffer = new Buffer(readSize);
        fs.read(fd, buffer, 0, readSize, 0, function (err, bytesRead, buffer) {
            callback();
        });
    });
};

I'm not really sure I believe C# is slower, given the following:

Running your node script, I receive:

Total iterations: 2000
Total time: 1199.8234639999998
Iterations per second: 1666.9118916314178

Running your C# script, as-is, I receive:

Total elapsed milliseconds was 1041.
Total iterations were 2000.
Total iterations per second was 1920.61576477911.

If I refactor it to use Parallel.For :

static Random r = new Random();

void Main()
{
     int iterations = 2000;

    Stopwatch s = new Stopwatch();
    s.Start();

    Parallel.For(0, iterations, ReadFile);

    s.Stop();

    Console.WriteLine("Total elapsed milliseconds was {0}.", s.ElapsedMilliseconds);
    Console.WriteLine("Total iterations were {0}.", iterations);
    Console.WriteLine("Total iterations per second was {0}.", iterations / s.Elapsed.TotalSeconds);
}

// Define other methods and classes here
static async void ReadFile(int x)
{
    string path = @"C:\Temp\random.txt";
    int readSize = r.Next(512, 10 * 1024);
    using (StreamReader reader = new StreamReader(path))
    {
        await reader.ReadAsync(new char[readSize], 0, readSize);
    }
}

I receive a pretty substantial performance gain:

Total elapsed milliseconds was 389.
Total iterations were 2000.
Total iterations per second was 5134.14889288497.

I'm also betting if I cached the buffer, in all scenarios, there would be another substantial bump. But, I can only go by performance on my local machine. And, from what I see, there's nothing that makes me think "oh wow, something is way off". I also don't know your environment. :shrug:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM