sqlite 时钟点击和unixepoch('now','subsec')

juud5qan  于 2023-10-23  发布在  SQLite
关注(0)|答案(2)|浏览(142)

我在记录某些程序的处理时间;但实际上并不是在比较不同的代码方法以生成相同的输出并确定哪种方法最有效方面的性能测试。
我只需要在用户与应用程序交互时生成的日志中添加一些时间间隔。现在,有两个主要项目我想知道涉及时间。一个是我记录是否需要搜索来完成请求,如果需要,需要多少步骤来定位项目。我想知道搜查花了多长时间。然后,一旦搜索完成,我想知道花了多长时间来执行该信息的操作,以满足请求。
Tcl中的clock clicks似乎是标记起点和沿着点的正确值。这项工作的大部分涉及将数据写入内存中的SQLite数据库,也可以使用unixepoch('now','subsec')
是一个比另一个更好,还是有一个更好的方法?
如果相关的话,我的目标之一(如果可能的话)是记录请求,以便再次运行它们并构建相同的日志,并比较代码的更改是否会在是否需要搜索、搜索步骤的数量和时间等方面产生任何差异。
谢谢你考虑我的问题。

xfyts7mz

xfyts7mz1#

这是我用来做你想要的东西的方法:

proc log_duration {msg script} {
    set cmds        [info cmdcount]
    set before      [clock microseconds]
    set code        [catch {uplevel 1 $script} res options]
    set elapsed     [expr {([clock microseconds] - $before) / 1e6}]
    set cmdcount    [expr {[info cmdcount] - $cmds - 12}]   ;# -12: compensate for measurement overhead
    set codename    [switch -- $code {
        0       {string cat OK}
        1       {string cat ERROR}
        2       {string cat RETURN}
        3       {string cat BREAK}
        4       {string cat CONTINUE}
        default {set code}
    }]
    puts "$msg, $codename: [format %.6f $elapsed] seconds, $cmdcount Tcl commands"
    dict incr options -level 1
    return -options $options $res
}

log_duration "Lookup the user details" {
    db eval {select id from users where name=:username}
}

我使用clock microseconds而不是clock clicks有几个原因:

  • 脚本不知道clock clicks的分辨率,因此很难报告有意义的持续时间。它也不与任何指定的时间点相关,这意味着它不能以人类有意义的方式格式化。
  • 在与我相关的最快的硬件上,单个字节编码的Tcl命令可以占用的最小时间大约是0.1微秒,并且可靠地测量接近该限制的任何内容都受到其他影响的影响,如处理器频率缩放(提升和节流以满足热预算),SMT和非对称内核调度,缓存状态,上下文切换以及一系列其他影响,这些影响使得对小间隔的有意义测量非常具有挑战性。
  • 在涉及多个主机的情况下,至少有希望clock microseconds返回的绝对值是可比的(至少在平台的时间同步可以实现的程度上)。
  • 使用CPU周期计数进行测量的想法(或者clock clicks碰巧有其他可用的东西)在频率缩放,睡眠状态,多核和核迁移,无序执行,深度管道等之前的日子里更有意义。

对于度量脚本的子部分,我通常只使用嵌套的log_duration调用。如果我在测量区域内移动探针,或者log_duration本身的开销成为问题,那么我通常会这样做:

proc ts label {
    global _timestamps
    lappend _timestamps [clock microseconds] $label
}

set ::_timestamps   {}
set start           [clock microseconds]

# ... some commands ...
ts foo
# ... some others ...
ts bar
# ... still more ...
ts baz
# ... you get the point ...

set last    $start
puts [join [lmap {ts label} $::_timestamps {
    try {
        format {%6d, %6d %s} [expr {$ts-$start}] [expr {$ts-$last}] $label
    } finally {
        set last   $ts
    }
}] \n]

lmap上构建单个puts有点尴尬,因为我通常在优化的事情之一是最小化日志调用时使用这种方法-通常这将在AWS CloudWatch中创建一个包含整个计时报告的条目。
满足您回放和比较测量结果的要求将取决于记录与运行相关的输入数据,当然这超出了测量代码的范围,而不是让测量框架的输出适合进行比较。clock microseconds通过测量一个一致的东西来做到这一点,这些例子输出的相对量应该在运行之间直接可比。
如果这些简单的方法不能解决问题,你需要在网络分布式环境中集中可视化时间戳事件,那么你可能会在我写的evlog包中找到一些有用的东西,嗯,前一段时间。重新运行可能并不难(Tcl在这方面很棒),大约13年前我将它从Itcl / Tk转换为TclOO,但我知道它使用了blt的table几何管理器,该管理器早已失效。我将blt包的组件拆分出来,并将其作为一个独立的包发布在某个地方,并为较新的Tk提供了一些修复,但我不记得在哪里(可能是Sourceforge)。将UI转换为使用grid可能比查找它更容易。但它也可能希望你把整个m2框架拉进来,这可能比它的价值要多,但它可能值得你从源代码中寻找想法。

1cklez4t

1cklez4t2#

clock中有四种可能的时间源:

  1. clock seconds
  2. clock milliseconds
  3. clock microseconds
  4. clock clicks
    前三个都有一个定义好的分辨率,大小很容易猜测(Tcl试图使用主机操作系统的合适计时器来获得与它们相当接近的实际精度),所有三个都使用Unix纪元的开始作为0时刻。他们不包; Tcl使用一个足够大的整数表示来保证这一点。
    相比之下,clock clicks(除非给定特定选项)使用可用的最高分辨率计时器(例如CPU性能计数器)和 * 任意 * epoch开始。也不能保证值是否环绕。

如果你是定时码,考虑使用timetimerate;前者更简单(并且非常适合长时间运行的代码的一次性测量),后者更适合微基准测试。在内部,他们将使用正确的时间源来完成工作。

相关问题