【问题标题】:What is the efficiency of using CPLEX with C#.NET vs C++?将 CPLEX 与 C#.NET 与 C++ 结合使用的效率如何?
【发布时间】:2014-04-30 13:58:44
【问题描述】:

如果我们的 UI 必须在 C#.NET 中...

将 C++ API 用于 CPLEX 与 C#.NET API 相比,性能是否会受到影响? 我想知道,因为如果可能的话,我想尽可能避免跨越托管/非托管边界,但我想更多地了解 C#.NET API 的情况。

C#.NET 是否只实现了 C++ 的托管/非托管边界?效果好吗?

【问题讨论】:

  • 当您分析代码时,性能优势在哪里?
  • 我还没有开始实施。
  • 使用不同优化级别的 C++ 编译器与 C# 编译器相比,效率降低。

标签: c# c++ .net cplex


【解决方案1】:

我们用 C++ 或 C# 甚至一些 Java 编写 CPLEX + Concert 代码已有大约 18 年了。这些是针对许多不同客户的许多独立项目。许多项目的首选最初是 C++,因为我们在 C# 出现之前就开始了。然后 C# 太新了,没有被广泛信任。但自 2005 年左右以来,我们一直更喜欢 C#,因为它更容易用 C# 编程。大约在 2004 年,我们做了一个项目,我们必须用 C++ 编写 CPLEX 建模代码,但必须使用 C# 数据库接口库(这是一个复杂的项目,这些选择背后的推理在今天没有意义)。使用 C# 和 C++ 之间的接口有一定的开销;但这些影响远小于使用 ado.net 与 odbc 等不同数据库访问方法之间的差异。

在实践中,对于我们的大多数项目,使用 C++ 所带来的额外效率提升非常小。通常,创建的系统将花费超过 90%(或 99%)的时间在 CPLEX 库调用中。我们遇到过很多情况,其中 C++ 或 C# 中的代码可能需要 1 或 2 分钟来读取和处理输入数据并创建 CPLEX 建模变量和约束,然后在 cplex.solve() 中解决问题需要 2-10 小时。因此,即使在 CPLEX 之外使用 C++ 而不是 C# 进行处理的速度快了十倍,但总体时间不会有太大变化。

如果您正在编写复杂的算法内容来构建和解决许多(小)模型(例如,如果您正在执行列生成或 LNS 或类似的操作),那么 C++ 可能会有可衡量的好处,但在更广泛的情况下可能不会太多。

我会选择您更喜欢使用的任何语言。正确编写代码比节省几秒钟更重要。

【讨论】:

  • 这非常有用。谢谢你。我主要担心的是,通过将 C# 和 C++ 一起编写来跨越边界,您会为代码的可维护性付出代价。
【解决方案2】:

official ILOG documentation 有话要说(强调我的):

对 API 方法的每次调用都会经过一个包装层。 这可能会在创建模型时产生轻微的性能开销与使用 C++ API 相比,具体取决于 API 函数调用的数量。由于您只调用很少的 API 函数来加载和求解模型,开销在通常情况下可以忽略不计,但如果您使用低级别的 Concert、CP Optimizer 或 CPLEX® API,它可能会变得很重要用于完整的模型创建(例如,使用 INumExpr API 逐行构造矩阵或使用 API 将 IConstraint 对象逐个添加到 IModel)。因此,建议尽可能使用 OPL 语言为您的问题建模,并仅将低级 Concert API 用于需要它的部分(运行时添加等)。

【讨论】:

  • 这正是我想要的。
  • 即使使用他们警告过的 API,在典型用法中开销也是微不足道的。事实上,我们将一个项目从使用 OPL 切换到使用低级别的 Concert 调用,并且模型设置时间减少了一半。实际的优化时间完全没有受到影响(您也不希望它受到影响)。我怀疑这取决于您的使用模式,尤其是您如何访问数据以提供给 Concert 或 OPL,但在我们的案例中,.NET 比 OPL 更快,而不是更慢。
【解决方案3】:

是的,C++ 更快,检查一下:

C# P/Invoke 为错误处理等增加了一些开销。

【讨论】:

  • C#.NET CPLEX API 是否使用 P/Invoke?
  • 到目前为止,我知道该库是用 C 编写的,它是从 C# 代码调用的,以确保您可以检查 c# 源代码。
  • 您不会看到在 CPLEX 中实现 .net 接口的 C# 源代码 - 它是专有产品,不是开源的。
  • 无关紧要。您使用 CPLEX 解决复杂的优化问题,这将比最复杂的 pinvoke 场景慢很多数量级。任何相关开销都不会来自基本 pinvoke 的使用,而是来自重构复杂数据结构的必要性(根据文档,情况似乎确实如此)。
  • @TimChippingtonDerrick 您可以通过反射或逆向工程等其他工具看到这一点。如果代码没有被混淆并且 99% 是安全的,那么很容易看到。
猜你喜欢
  • 1970-01-01
  • 2016-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-07
  • 1970-01-01
相关资源
最近更新 更多