【问题标题】:C++ Benchmark toolC++ 基准测试工具
【发布时间】:2011-07-18 18:59:56
【问题描述】:

我有一些应用程序,它发出数据库请求。 我想这实际上并不重要,我使用什么样的数据库,但假设它是一个简单的SQLite驱动的数据库。

现在,此应用程序作为服务运行,每分钟执行一定数量的请求(这个数字实际上可能很大)。

我愿意对查询进行基准测试以检索它们的数量、一段时间内的最大/最小/平均运行时间,并且我希望为此设计自己的工具 (显然,有一些,但我需要我的出于某些适当的原因拥有 :)。

那么 - 你能为这项任务提供一种方法吗?


我猜有几种可能的情况:

1) 我可以访问应用程序源代码。 很明显,我想进行某种跨应用程序集成,可能使用管道。就应该如何完成以及(如果有的话)任何其他可能的解决方案提出建议?

2) 我没有资源。那么,这是否可以从我的应用程序中执行一些巧妙的注入来对另一个应用程序进行基准测试? 我希望有办法,也许是 hacky,随便什么。

非常感谢。

【问题讨论】:

  • @John Unix 没问题,多平台解决方案是最好的。
  • 对我来说听起来像是一个“SQL 基准测试工具”。不是 C++ 的。您对 SQL 查询的性能感兴趣。
  • 哇,这几乎是你代表的 30%。哇...
  • 我会重新开始here
  • @quasiverse 我有另一个 25k 的帐户,所以我想这不是问题 :)

标签: c++ database integration benchmarking connection


【解决方案1】:

查看C++ Code Profiler 了解一系列分析器。

C++ Logging and performance tuning library 滚动您自己的简单版本

【讨论】:

    【解决方案2】:

    我的回答仅对案例 1) 有效。

    根据我的经验,分析是一项有趣且艰巨的任务。使用专业工具可能很有效,但要找到合适的工具并学习如何正确使用它可能需要很多时间。我通常以一种非常简单的方式开始。我准备了两个非常简单的类。第一个 ProfileHelper 类在构造函数中填充开始时间,在析构函数中填充结束时间。第二类 ProfileHelperStatistic 是一个具有额外统计能力的容器(一个 std::multimap + 一些返回平均值、标准差和其他有趣内容的方法)。

    ProfilerHelper 具有对容器的引用,并且在退出析构函数之前将数据推送到容器中。您可以在 main 中声明 ProfileHelperStatistic,如果您在特定函数的开头在堆栈上创建 ProfilerHelper,则工作完成. ProfileHelper 的构造函数将存储开始时间,析构函数将结果推送到 ProfileHelperStatistic。

    实现起来相当容易,只需稍加修改即可实现跨平台。不记录创建和销毁对象的时间,因此不会污染结果。计算最终统计数据可能会很昂贵,因此我建议您在最后运行一次。

    您还可以自定义要存储在 ProfileHelperStatistic 中的信息,添加额外信息(例如时间戳或内存使用情况)。

    实现相当简单,两个类,每个类不超过 50 行。只有两个提示:

    1) 在析构函数中捕获所有内容!

    2) 如果要存储大量数据,请考虑使用需要固定时间插入的集合。

    这是一个简单的工具,它可以帮助您以非常有效的方式分析您的应用程序。我的建议是从几个宏函数(5-7 个逻辑块)开始,然后增加粒度。记住 80-20 规则:20% 的源代码使用 80% 的时间。

    关于数据库的最后一点:数据库动态调整性能,如果您在最后多次运行查询,查询将比开始时更快(Oracle 会,我猜其他数据库也是如此)。换句话说,如果您对只关注少数特定查询的应用程序进行大量人工测试,您可能会得到过于乐观的结果。

    【讨论】:

    • 虽然这不是一个完整的答案,但它给了我一些思考的想法。谢谢。
    【解决方案3】:

    我想这实际上并不重要, 我正在使用什么样的数据库, 但让我们说这是一个简单的 SQLite 驱动的数据库。

    使用什么样的数据库非常重要,因为数据库管理器可能集成了监控。

    我只能谈论 IBM DB/2,但我相信 IBM DB/2 并不是唯一具有集成监控工具的 dbm。

    例如,这里简要概述了您可以在 IBM DB/2 中监控的内容:

    • 语句(所有已执行语句、执行计数、准备时间、cpu 时间、读/写计数:表行、缓冲池、逻辑、物理)
    • 表(读/写计数)
    • 缓冲池(数据和索引的逻辑和物理读/写、读/写时间)
    • 活动连接(运行语句、读/写计数、次数)
    • 锁(所有锁和类型)
    • 还有更多

    可以从自己的软件通过 SQL 或 API 访问监控数据,例如 DB2 Monitor

    【讨论】:

      【解决方案4】:

      在 Unix 下,您可能想要使用 gprof 及其图形前端 kprof。使用 -pg 标志编译您的应用程序(我假设您使用的是 g++)并通过 gprof 运行它并观察结果。

      但是请注意,这种类型的分析将衡量应用程序的整体性能,而不仅仅是 SQL 查询。如果您要测量查询的性能,您应该使用专为您的 DBMS 设计的特殊工具 - 例如,MySQL 有一个内置的查询分析器(对于 SQLite,请参阅此问题:Is there a tool to profile sqlite queries?

      【讨论】:

        【解决方案5】:

        有一个 (linux) 解决方案您可能会觉得有趣,因为它可以用于两种情况。

        这是 LD_PRELOAD 的把戏。它是一个环境变量,可让您在程序执行之前指定要加载的共享库。从此库加载的符号将覆盖系统上任何其他可用的符号。

        基本思想是将此自定义库作为原始函数的包装器。

        有很多资源可以解释如何使用这个技巧:123

        【讨论】:

          【解决方案6】:

          显然,我想进行某种跨应用程序集成,可能使用管道。

          我认为这一点都不明显。

          如果您有权访问该应用程序,我建议您将所有必要信息转储到一个日志文件中,然后再处理该日志文件。 如果您希望能够在不重新启动服务的情况下即时激活和停用此行为,则可以使用支持动态启用/禁用日志通道的日志库。 然后,您只需要通过任何方式(套接字连接,...)向服务发送消息即可启用/禁用日志记录。

          如果您无权访问该应用程序,那么我认为最好的方法是 MacGucky 的建议:让 DBMS 的分析/监控工具来做。例如。 MS-SQL 有一个很好的分析器,可以捕获对服务器的请求,包括各种有用的数据(每个请求的 CPU 时间、IO 时间、等待时间等)。

          如果真的是SQLite(加上您无权访问源代码),那么您的机会就相当低了。如果有问题的程序使用 SQLite 作为 DLL,那么您可以替换您自己的 SQLite 版本,修改为写入必要的日志文件。

          【讨论】:

            【解决方案7】:

            使用 apache jmeter。 测试高负载下 sql 查询的性能

            【讨论】:

              猜你喜欢
              • 2010-09-20
              • 2011-04-28
              • 1970-01-01
              • 1970-01-01
              • 2018-09-09
              • 2011-01-26
              • 2013-08-22
              • 2013-08-17
              • 2017-11-07
              相关资源
              最近更新 更多