【问题标题】:Excel VBA: Macro for data processing getting slower and slower the longer it runs [closed]Excel VBA:数据处理的宏运行时间越长越慢[关闭]
【发布时间】:2012-10-17 04:13:14
【问题描述】:

我正在使用 32 位 Excel 2010 中的 QuantlibXl 库分析大量历史财务数据。我的典型工作表包含长达 100 万行的长列经验数据。我的宏通常需要从上到下遍历每一行,并执行一些 Quantlib 典型的财务分析工作,例如重新评估证券,这需要在每一行中创建 Quantlib 对象。分析内容以公式的形式包含在单元格中。

所以一开始我尝试只选择顶行中带有公式的单元格,然后通过将右下角拖动到工作表底部来填充它们。在这里,处理时间随着所涉及的行数呈指数增长。

所以我想我必须编写一个宏来一次处理较小的行块。该宏基本上会一次只填充顶行 100 行。这和一些优化(如下所述)无疑极大地提高了速度,但处理时间仍然呈指数级增长。

问题在于,尽管我尝试优化我的宏,但它们运行的​​时间越长,它们就会变得越来越慢。我在状态栏中跟踪已处理的行,例如,如果在启动宏时每分钟处理 2000 行(计算非常复杂),它的速度在整个运行时不断降低,例如每分钟只有 100 行60,000 行后的分钟。在那种节奏下,它永远不会看到工作表的结尾。所以事实上,在某些时候,最好中止它并从它停止的地方重新启动它。我还拆分了文件,让它们同时在不同的计算机上运行,​​这在管理方面很麻烦。

我已经实施了大量优化: - 屏幕更新和自动计算已关闭。 - 我一次只对正在处理的行执行计算。 - 垃圾收集:Quantlib 对象在不再使用后立即被删除。我认为是他们吃掉了所有的空闲内存导致了减速。 - 到目前为止,我已将相关结果(单元格)写入文本文件并删除不再需要的行。同样,宏在开始时非常快,如果在 70,000 行之后它不再变慢,它会在几个小时内运行到结束。事实上,我曾希望在运行时看到速度提高,因为行被删除并且工作表缩小,但这并没有发生。所以我只是不停地停止这个过程,直到 60,000 行,然后重新启动它,但它很烦人。

我想弄清楚是什么原因导致 Excel 无法线性处理大量数据并需要重新启动,以及如何避免这种行为。如果有人遇到类似的麻烦并找到解决方法,我会很高兴听到的。

编辑: 每次我停止该过程以通过重新开始再次加快速度时,我注意到我必须重新启动 Excel,否则它会像以前一样缓慢恢复。我目前的假设是,在某些时候数据没有被正确清理。如果是这种情况,您的解决方案将使我更进一步。 Quantlib 库有一个方法来查看有多少对象仍然驻留在内存中,称为 ohRepositoryObjectCount()。我在每次计算后调用 ohRepositoryDe​​leteAllObjects() 函数,并且按照其他方法有效地删除了它们,但可能仍然存在一些未被检测到的泄漏。

EDIT2:我现在确信存在内存泄漏,因为在长时间批处理后,任务管理器显示 3 或 4 个 Excel 进程一起消耗了大约 1.5 GB 的内存。退出 Excel 时,它会崩溃(并显示“Excel 不再工作”的消息),并且进程仍然存在,因此我必须手动终止它们。

【问题讨论】:

  • 很难准确说出问题所在,但发布一些实际代码会有所帮助。您是否一直在监控较长时间的内存使用情况 - 是否有可能存在导致速度减慢的泄漏?
  • 运行时 Excel 的内存使用范围从 0.5 GB 到 1 GB,即使对于 32 位版本的 Excel 也没什么特别的。我不认为发布一些代码会有所帮助,因为大部分操作都发生在 QuantlibXl 的 XLL 插件中。
  • 可能是您使用的 quantlib 库有问题。如果您熟悉 vba,您是否尝试过编写自己需要的功能?
  • 一些 QuantlibXL 的功能似乎旨在更新,即使在 Excel 中关闭自动计算 - 请参阅 quantlib.org/quantlibxl/observer.html - 并且使用永久对象 - 详细信息在 quantlib.org/quantlibxl/references.html - 可以规避通常的垃圾收集进程
  • @JMK:其实大部分现金流折现都是很基础的,我自己也已经实现了。但是 Quantlib 擅长的地方在于考虑各种市场惯例,比如如何计算天数。许多金融专业人士正是为此使用 Quantlib。

标签: excel vba optimization large-data


【解决方案1】:

如果我的假设是正确的,那么您的行就是您所有证券的列表;并且彼此不相关;你不用计算它们。如果正确,请执行以下操作:

  1. 在单独的工作表上,布局所有数据列(输入和 输出)来表示一行。
  2. 从“源”工作表中复制并粘贴一行数据中的值。
  3. 从源表中删除所有计算并将其放入此处。
  4. 将值复制并粘贴回您的源工作表。

将 #2 到 #4 放入宏中并循环遍历您的数据。

这就是我的回答,以下只是评论。如果我这样做:

  1. 我的“源”数据将在数据库中。我确定有关系 在我想探索的证券中。
  2. 为了便于阅读,我会将行元素转换为计算表上的一列。
  3. 为了便于阅读,我会将计算拆分为多个列和部分。

【讨论】:

  • 你的假设是正确的。如果我理解正确,您将拥有一个源工作表(或数据库表),其中一个计算所需的所有值都被复制到一个“工作”表中,所有操作都在其中发生。我可以试试这个,但不认为它会进一步帮助。每次我通过重新开始来停止该过程以再次加快速度时,我注意到我必须重新启动 Excel,否则它会像以前一样缓慢地恢复。我目前的假设是,在某些时候数据没有被正确清理。如果是这种情况,您的解决方案会让我更进一步。
  • 这与重新计算有关,因为您没有通过粘贴值“杀死”公式。
  • 这不是真的,在我早期的尝试中,我使用公式将值粘贴到单元格上;后来我让宏在计算后删除了带有公式的行。主要问题仍然存在。我猜这暗示了 Quantlibxl 库中的内存泄漏错误。
猜你喜欢
  • 1970-01-01
  • 2022-11-12
  • 2016-07-13
  • 2022-11-03
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多