【问题标题】:Is using different thread pools for different types of tasks worth the overhead?为不同类型的任务使用不同的线程池是否值得开销?
【发布时间】:2018-02-16 20:53:37
【问题描述】:

我正在设计一个类,它提供有关 Collat​​z 序列组的统计信息。我的目标之一是能够以最高的效率同时处理大量包含大量术语(数百甚至数千位数)的序列。

为此,我计划对每个单独的统计数据使用最佳数据收集技术,这意味着ForkJoinPool 可以更有效地处理某些任务,而@987654322 中提供的标准缓存和固定线程池可以更有效地处理其他任务@。如果我走这条路,创建多个线程池或关闭一个并创建另一个线程池的开销是否会比我节省的更多?

【问题讨论】:

  • 这可能需要您根据经验进行测试。

标签: java multithreading threadpool


【解决方案1】:

由于您只谈论两种不同类型的池(fork-join 和基于Executor 的池),并且您声称至少您的一些任务更适合一种类型或池或其他类型,因此它是完全有可能使用两种类型的池的开销是值得的。

毕竟,您可以让这两种类型的池保持活动状态,因此设置池和创建线程只需一次成本,而两者的(明显)好处池类型将适用于您的整个处理过程。由于您正在做“巨大”的工作,因此即使是很小的收益最终也会加起来并压倒一次性成本(可能以每个线程的微架构来衡量)。

此观察的关键是,对于您未使用的池中现有但不活动的线程,没有真正的持续开销。

当然,也就是说,简短的回答是“只需尝试两种方法并测量它!”。

【讨论】:

    【解决方案2】:

    如果我走这条路,创建多个线程池或关闭一个并创建另一个线程池的开销是否会超过我节省的成本?

    我们怎么可能告诉你呢?

    关闭和重新启动线程池肯定会产生开销。如果有的话。创建线程并不便宜。

    但是,我们无法量化使用不同类型的线程池节省了多少。如果我们无法量化,就无法就您的策略是否有效......向您提供建议。

    (但我认为反复关闭和​​重新创建线程池是个坏主意。idle 池对性能的影响很小。)


    这有过早优化的“味道”。 (这就像在制造发动机组之前尝试调整赛车的发动机!)

    我的建议是(很大程度上1)从一开始就忘记性能。现在,专注于获得有效的东西。这就是我要做的:

    1. 使用最简单的策略实现代码,编写测试用例,测试/调试直到它工作。
    2. 选择您将尝试解决的典型问题的示例问题或一组问题
    3. 实施一个测试工具,允许您针对示例问题测量代码的性能。 (注意 Java 基准测试的标准问题...)
    4. 对您的代码进行基准测试。
      • 是否足够快?立即停止。
      • 如果没有,请继续。
    5. 实施一种替代策略,并进行测试/调试。
    6. 对修改后的代码进行基准测试。
      • 是否足够快?立即停止。
      • 很明显它没有帮助吗?放弃它,尝试其他策略。
      • 你能调整一下吗?如果是这样,请尝试。
    7. 转到5。

    此外,以这样一种方式实施不同的策略可能是值得的,您可以使用命令行或配置文件设置调整它们或在它们之间切换。


    作为一般规则,很难先验确定任何复杂的算法或策略的执行情况。一般来说,有太多的因素需要考虑到一个理论......或直觉......方法来给出一个可靠的预测。基准测试和调整是要走的路。


    1 - 显然,如果您知道某些技术或算法会表现不佳,并且您有一个更好的替代方案,而且实现起来的努力大致相同......做明智的事情.

    【讨论】:

    • 我对并发比较陌生,我想确保我的计划不是并发程序员中最大的“禁忌”之一。但你是对的。我倾向于完美主义和过度分析事物,因此我不得不强迫自己避免过早的优化。
    • 这不是一个大禁忌。我会说这是似是而非的。过早优化的问题是 1) 你经常在不需要的时候优化(浪费时间),2) 你经常优化错误的东西(浪费时间),或者 3) 你的优化可能会变成反优化.
    猜你喜欢
    • 2014-01-31
    • 2020-09-24
    • 2011-05-02
    • 2010-09-07
    • 2017-10-15
    • 2012-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多