Я пытаюсь увеличить количество одновременных асинхронных вызовов, которые я могу сделать в C#. В частности, я стараюсь соответствовать производительности, которую я вижу в Node.js.Как увеличить количество одновременных асинхронных вызовов?
Ниже приведены два примера программ, один в C# и один в JavaScript. Оба считывают случайное число байтов в буфер из 10 МБ файла, содержащего случайные числа, а затем выполняют эту операцию 2000 раз асинхронно. Программа JavaScript может делать это примерно 60 000 раз в секунду на моей машине, но программа C# может делать только около 3000. Насколько я могу судить, они делают то же самое, но я понимаю, что есть определенные отличия.
У меня были аналогичные тесты с различными функциями, в том числе спящие в течение небольшого количества времени, и выполнение вставок в кластер Cassandra с использованием драйверов Datastax Cassandra. Последняя функциональность - это то, что я действительно пытаюсь улучшить, поскольку я могу получить около 80 вставок в секунду на C#, но около 5000 в узле.
Может кто-нибудь помочь мне объяснить это несоответствие?
// 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();
});
});
};
Если вы используете downvote, объясните, почему я могу улучшить вопрос. –
Незначительное усиление производительности с помощью 'Parallel.For (...)' над созданием коллекции с помощью 'Enumerable' и ожидающей' Task.WaitAll'. (Я достиг ~ 5134.15/сек) –
@BradChristie Я вижу такое же улучшение - около 5000-6000 итераций в секунду. Он все еще намного ниже 60 000-70 000, который я получаю с Узел. К сожалению, «Parallel.For», похоже, не улучшает мои вызовы Cassandra (что на самом деле является частью причины, по которой я перешел в «Task.WaitAll» изначально). –