首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ksh_timer 时间接口初级

ksh_timer 时间接口初级

简介ksh_timer 被设计用来帮助 ksh 或 ksh93 脚本管理员或开发人员计算每个函数及其 shell 脚本用户定义部分所用的时间。
以下几个要点定义了 ksh_timer 的功能:
  • 如果在 ksh_timer 中运行脚本,那么该脚本调用的函数是自动计时的。
  • 用户使用 ##KTB <section_name>(这部分的开始)和 ##KTE <section_name>(这部分的结束)在脚本中心定义相关部分。
  • 给出的时间是总运行时间,不是已使用的时间。
  • 输出包括 « Main » 时间,这是脚本的总运行时间。
  • 还包括去向不明的输出时间,这些时间是花费在函数或用户定义部分之外的 « Main » 部分中的时间。
  • 去向不明的时间还包括计算函数引起的 ksh_timer 开销。
  • ksh_timer 支持 ksh 和 ksh93 脚本的执行。
  • 使用:ksh_timer [-D] [-c] [-?] [-s] [script name arguments ...]
    • -D 将 ksh_timer 置于调试模式。
    • -c 保留原始输出文件 (ksh_timer.<script_name>.<pid>.out)。通常在执行后删除。
    • -s [script name arguments ...] 脚本文件名和脚本所需参数。
    • -? 打印使用情况。
重要提示该接口 (ksh_timer) 是为了用户方便而提供的。本文使用一个样例程序说明了 ksh_timer 的用法和功能,工具是按原样提供的,我们不提供任何担保和支持。
该工具已在 IBM® AIX® 5.3,6.1 和 7.1 版本上进行了测试。ksh_timer 可以用于其他操作系统,要实现这一点,必须使用本文安装 小节中提供的源代码,为该操作系统重新构建 ksh_timer_c 可执行文件。
概述在启动时,ksh_timer 会读取命令行提供的输入脚本,然后从中构建以下 3 个文件(源文件、计时器文件和 exec 文件)。
  • 源文件包含原函数定义,并且来自 exec 文件。
  • 计时器文件包含包括计时代码和调用原函数的封装函数。计时器文件也来自 exec 文件。在下列示例中,原函数 f1 在源文件中被重命名为 f1_orig ,而在计时器文件中,f1 有一个计时代码包含 f1_orig 函数,该函数使我们能够得到原函数 f1 所耗的时间。
  • exec 文件是源文件和计时器文件的来源,而且包含原始 main 代码以及用于任何用户定义部分的计时器代码。
当完成这些文件的构建之后,ksh_timer 会运行构建 exec 文件。运行原始代码时,该函数会计算函数和用户定义部分的运行时间,并将这些时间写入输出文件。执行完这些操作之后,它会分析输出文件,然后计算函数名、缩进、迭代次数以及这些函数或代码部分的最小、最大、平均和总运行时间,并将它们显示在屏幕上。
  • 使用以下输入脚本样例:ksh_timer.test_pres
1
2
3
4
5
6
7
8
9
10
11
#! /usr/bin/ksh
f1()
{
echo "hello"
}
#Main
##KTB user_defined_section
sleep 1
f1##KTE user_defined_section
sleep 2
f1




  • 源文件:包含原始函数定义
1
2
3
4
f1_orig()
{
echo "hello"
}




  • 计时器文件:包含包括计时代码和调用原函数的封装函数
1
2
3
4
5
6
7
8
9
10
11
12
function f1
{
time1f1=`/home/albl/ksh_timer/ksh_timer_c`
ksh_timer_add_func f1
f1_orig $*
f1_orig_rc=$?
time2f1=`/home/albl/ksh_timer/ksh_timer_c`
let " time3f1 = $time2f1 - $time1f1"
print "$indent1indent2indent3indent4indent5time3f1" >&9
ksh_timer_remove_func f1
return $f1_orig_rc
}




  • exec 文件:包含用于任何用户定义部分的原始代码和计时器代码
1
2
3
4
5
6
7
8
9
10
11
12
. ./ksh_timer.test_pres.413914.source
. ./ksh_timer.test_pres.413914.timer
time1user_defined_section=`/home/albl/ksh_timer/ksh_timer_c`
ksh_timer_add_func user_defined_section
sleep 1
f1
time2user_defined_section=`/home/albl/ksh_timer/ksh_timer_c`
let "time3user_defined_section=$time2user_defined_section-$time1user_defined_section"
print "$indent1indent2indent3indent4indent5time3user_defined_section" >&9
ksh_timer_remove_func user_defined_section
sleep 2
f1




  • 运行该样例得到下列输出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ ./ksh_timer -s ./sample
----------------------Start of sample output--------------------------------
hello
hello
----------------------End of sample output--------------------------------
------------------------------------------------------------------------------------------
|    function   |     Minimum       |     Maximum       |   Average  |       Total       |
|               +-------------------+-------------------+------------+-------------------|
|   or Section  |iter.#|   time     |iter.#|   time     |   time     |#iter.|   time     |
|---------------+------+------------+------+------------+------------+------+------------|
|Main           |                                                           |0m03.092834s|
|---------------+------+------------+------+------------+------------+------+------------|
|-user_defined|     1|0m01.027853s|     1|0m01.027853s|0m01.027853s|     1|0m01.027853s|
|--f1           |     1|0m00.003143s|     1|0m00.003143s|0m00.003143s|     1|0m00.003143s|
|-f1            |     1|0m00.002652s|     1|0m00.002652s|0m00.002652s|     1|0m00.002652s|
|---------------------------------------------------------------------------+------------|
|-Unaccounted   |                                                           |0m02.062329s|
------------------------------------------------------------------------------------------




正如我们所看到的,user_defined_section 被调用了一次,在 user_defined_section 中 f1 函数被调用了一次,在该脚本的主要部分中,f1 也被调用了一次。user_defined_section 所用时间是 1 秒多一点,这主要是步骤 1 以及 f1 函数所用的时间。去向不明时间大约有 2 秒,这主要是所有部分或函数外部的步骤 2 所用时间,以及 ksh_timer 计算时间所需的开销。
用户定义部分计时器代码与执行代码保持关联,以便能够在这些部分的内部使用传递给 shell 脚本的参数。ksh_timer 输出将以一种易于阅读的表格形式发送到屏幕(稍后给出相关示例)。如果您选择将输出发送到某个文件,那么将以下列格式输出每次迭代:
1
Main:indent1:…:indent9:>time_spent<




(缩进 1 到 9  的输出可能是调用函数的函数名,或者如果函数深度没有达到那么深的话,输出则为空。)例如:
1
Main:user_defined_section:f1:::::::3143




(我们在 f1 函数中花费的时间为 3143 微秒,user_defined 调用了该函数,而 user_defined 反过来是从主要部分调用的。)
安装 ksh_timer
  • 您可以从 下载 部分下载 ksh_timer。
  • 要完成安装,首先应该将 ksh_timer.tar 文件解压到任意目录下。
  • 您可能需要编辑将要实现计时功能的原始脚本来添加带有 « ##KTB <section_name> » 和 « ##KTE <section_name> 定义的用户定义部分。
  • 要完成执行,请运行 ./ksh_timer –s <your_script>。
  • 输出被发送到屏幕上;如果指定了 –c 的话,则会将原始数据发送到文件 ksh_timer.<script name>.<ID>.out。
  • 如果运行一个非 AIX 系统,ksh_timer_c 代码需要从以下 ksh_timer_c.c 源代码重构:
1
2
3
4
5
6
7
8
#include <stdio.h>
#include <sys/time.h>
main()
{
struct timeval Tp;
gettimeofday(&Tp,NULL);
printf("%lld\n",(unsigned long long)((Tp.tv_sec*1000000)+Tp.tv_usec));
}

返回列表