- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想比较两个理论场景。为了问题的目的,我简化了案例。但基本上它是您典型的生产者消费者场景。 (我关注的是消费者)。
我有一个很大的Queue
我必须将其传输给多个客户端。
那么让我们从更简单的情况开始:
class SequentialBlockingCase
{
public static Queue DataQueue = new Queue();
private static List _destinations = new List();
///
/// Is the main function that is run in its own thread
///
private static void Run()
{
while (true)
{
if (DataQueue.Count > 0)
{
string data = DataQueue.Dequeue();
foreach (var destination in _destinations)
{
SendDataToDestination(destination, data);
}
}
khác
{
Thread.Sleep(1);
}
}
}
private static void SendDataToDestination(string destination, string data)
{
//TODO: Send data using http post, instead simulate the send
Thread.Sleep(200);
}
}
}
现在这个设置工作得很好。它坐在那里并轮询 Hàng đợi
当有数据要发送时,它会将其发送到所有目的地。
câu hỏi:
这是我的第二次尝试:
class ParalleBlockingCase
{
public static Queue DataQueue = new Queue();
private static List _destinations = new List();
///
/// Is the main function that is run in its own thread
///
private static void Run()
{
while (true)
{
if (DataQueue.Count > 0)
{
string data = DataQueue.Dequeue();
Parallel.ForEach(_destinations, destination =>
{
SendDataToDestination(destination, data);
});
}
khác
{
Thread.Sleep(1);
}
}
}
private static void SendDataToDestination(string destination, string data)
{
//TODO: Send data using http post
Thread.Sleep(200);
}
}
如果 1 个目的地速度慢或不可用,此修订至少不会影响其他目的地。
但是这个方法仍然是阻塞的,我不确定 Parallel.ForEach
使用线程池。我的理解是它将创建 X 个线程/任务并一次执行 4 个(4 个核心 cpu)。但它必须在任务 5 开始之前完成任务 1 的芬兰语。
因此我的第三个选择:
class ParalleAsyncCase
{
public static Queue DataQueue = new Queue();
private static List _destinations = new List { };
///
/// Is the main function that is run in its own thread
///
private static void Run()
{
while (true)
{
if (DataQueue.Count > 0)
{
string data = DataQueue.Dequeue();
List tasks = new List();
foreach (var destination in _destinations)
{
var task = SendDataToDestination(destination, data);
task.Start();
tasks.Add(task);
}
//Wait for all tasks to complete
Task.WaitAll(tasks.ToArray());
}
khác
{
Thread.Sleep(1);
}
}
}
private static async Task SendDataToDestination(string destination, string data)
{
//TODO: Send data using http post
await Task.Delay(200);
}
}
现在根据我的理解这个选项,仍然会阻塞在 Task.WaitAll(tasks.ToArray());
的主线程上这很好,因为我不希望它因为创建任务的速度快于执行速度而跑掉。
但是并行执行的任务应该使用ThreadPool
,并且所有 X 个任务应该立即开始执行,而不是阻塞或按顺序执行。 (线程池将在它们变为事件状态或 awaiting
时在它们之间交换)
现在我的问题。
选项 3 是否比选项 2 有任何性能优势。
特别是在更高性能的服务器端场景中。在我现在正在开发的特定软件中。上面会有我的简单用例的多个实例。即多个消费者。
我对这两种解决方案的理论差异和优缺点很感兴趣,如果有的话,可能还有更好的第四种选择。
câu trả lời hay nhất
Parallel.ForEach
将使用线程池。异步代码sẽ không,bởi vìit doesn't need any threads at all (链接是我的博客)。
正如 Mrinal 指出的那样,如果您的代码受 CPU 限制,则并行是合适的;如果您有 I/O 绑定(bind)代码,异步是合适的。在这种情况下,HTTP POST 显然是 I/O,因此理想的消费代码应该是异步的。
maybe even a better 4th option if there is one.
我建议让您的消费者完全异步。为此,您需要使用异步兼容的生产者/消费者队列。有一个相当高级的( BufferBlock
) in the TPL Dataflow library ,和一个相当简单的 ( AsyncProducerConsumerQueue
) in my AsyncEx library .
使用它们中的任何一个,您都可以创建一个完全异步的消费者:
List tasks = new List();
foreach (var destination in _destinations)
{
var task = SendDataToDestination(destination, data);
tasks.Add(task);
}
await Task.WhenAll(tasks);
或者更简单地说:
var tasks = _destinations
.Select(destination => SendDataToDestination(destination, data));
await Task.WhenAll(tasks);
关于c# - 重 I/O 操作中的 Parallel.ForEach 与异步 For 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39075845/
在使用 requests 库中的状态代码时,我遇到了一些奇怪的事情。每个 HTTP 状态代码都有一个常量,有些具有别名(例如,包括 200 的复选标记): url = 'https://httpbin
这是我得到的代码,但我不知道这两行是什么意思: o[arr[i]] = o[arr[i]] || {}; o = o[arr[i]]; 完整代码: var GLOBAL={}; GLOBAL.name
所以这个问题的答案What is the difference between Θ(n) and O(n)? 指出“基本上,当我们说算法是 O(n) 时,它也是 O(n2)、O(n1000000)、O
这是一个快速的想法;有人会说 O(∞) 实际上是 O(1) 吗? 我的意思是它不依赖于输入大小? 所以在某种程度上它是恒定的,尽管它是无限的。 或者是唯一“正确”的表达方式 O(∞)? 最佳答案 无穷
Điều này có đúng không: log(A) + log(B) = log(A * B) [0] Điều này cũng đúng phải không? O(log(A)) + O(log(B)) = O(log(A * B)) [1] Theo như tôi hiểu thì O(f
我正在解决面试练习的问题,但我似乎无法找出以下问题的时间和空间复杂度的答案: Given two sorted Linked Lists, merge them into a third list i
我了解 Big-Oh 表示法。但是我该如何解释 O(O(f(n))) 是什么意思呢?是指增长率的增长率吗? 最佳答案 x = O(n)基本上意味着 x <= kn对于一些常量 k . 因此 x = O
我正在编写一个函数,该函数需要一个对象和一个投影来了解它必须在哪个字段上工作。 我想知道是否应该使用这样的字符串: const o = { a: 'Hello There' }; funct
直觉上,我认为这三个表达式是等价的。 例如,如果一个算法在 O(nlogn) + O(n) 或 O(nlogn + n) 中运行(我很困惑),我可以假设这是一个O(nlogn) 算法? 什么是真相?
根据 O'Reilly 的 Python in a Nutshell 中的 Alex Martelli,复杂度类 O(n) + O(n) = O(n)。所以我相信。但是我很困惑。他解释说:“N 的两个
O(n^2)有什么区别和 O(n.log(n)) ? 最佳答案 n^2 的复杂性增长得更快。 关于big-o - 大 O 符号 : differences between O(n^2) and O(n
Bất cứ khi nào tôi nhận được email từ MS Outlook, tôi nhận được dấu này (không có dấu cách) xuất hiện dưới dạng? trong <>. Khi tôi thay đổi nó thành ISO-8859-1, bộ ký tự trang trình duyệt được mã hóa dưới dạng UTF-8.
我很难理解 Algorithms by S. Dasgupta, C.H. Papadimitriou, and U.V. Vazirani - page 24 中的以下陈述它们将 O(n) 的总和表
我在面试蛋糕上练习了一些问题,并在问题 2给出的解决方案使用两个单独的 for 循环(非嵌套),解决方案提供者声称他/她在 O(n) 时间内解决了它。据我了解,这将是 O(2n) 时间。是我想错了吗,
关于 Java 语法的幼稚问题。什么 T accept(ObjectVisitorEx visitor); 是什么意思? C# 的等价物是什么? 最佳答案 在 C# 中它可能是: O Accept(
假设我有一个长度为 n 的数组,我使用时间为 nlogn 的排序算法对它进行了排序。得到这个排序后的数组后,我遍历它以找到任何具有线性时间的重复元素。我的理解是,由于操作是分开发生的,所以时间是 O(
总和 O(1)+O(2)+ .... +O(n) 的计算结果是什么? 我在某处看到它的解决方案: O(n(n+1) / 2) = O(n^2) 但我对此并不满意,因为 O(1) = O(2) = co
这个问题在这里已经有了答案: 11 年前关闭。 Possible Duplicate: Plain english explanation of Big O 我想这可能是类里面教的东西,但作为一个自学
假设我有两种算法: for (int i = 0; i 2)更长的时间给定的一些n - 其中n这种情况的发生实际上取决于所涉及的算法 - 对于您的具体示例, n 2)分别时间,您可能会看到: Θ(n)
这个问题在这里已经有了答案: Example of a factorial time algorithm O( n! ) (4 个回答) 6年前关闭。 我见过表示为 O(X!) 的 big-o 示例但
Tôi là một lập trình viên xuất sắc, rất giỏi!