歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Unix知識 >> Unix基礎知識 >> ksh_timer時間接口

ksh_timer時間接口

日期:2017/3/3 15:23:19   编辑:Unix基礎知識

簡介

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

#! /usr/bin/ksh
f1()
{
echo "hello"
}
#Main
##KTB user_defined_section
sleep 1
f1
##KTE user_defined_section
sleep 2
f1

源文件:包含原始函數定義

f1_orig()
{
echo "hello"
}

計時器文件:包含包括計時代碼和調用原函數的封裝函數

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 "$indent1:$indent2:$indent3:$indent4:$indent5:$time3f1" >&9
ksh_timer_remove_func f1
return $f1_orig_rc
}

exec 文件:包含用於任何用戶定義部分的原始代碼和計時器代碼

. 

./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 "$indent1:$indent2:$indent3:$indent4:$indent5:$time3user_defined_section" >&9
ksh_timer_remove_func user_defined_section
sleep 2
f1

運行該樣例得到下列輸出:

$ ./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 輸出將以 一種易於閱讀的表格形式發送到屏幕(稍後給出相關示例)。如果您選擇將輸出發送到某個文件,那麼將 以下列格式輸出每次迭代:

Main:indent1:…:indent9:>time_spent<

(縮進 1 到 9 的輸出可能是調用函數的函數名,或者如果函數深度沒有達到那麼深的話,輸出則為空。)例如 :

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>.<PID>.out。

如果運行一個非 AIX 系統, ksh_timer_c 代碼需要從以下 ksh_timer_c.c 源代碼重構:

#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));
}

使用示例

想象一下,如果有下列腳本 script_test_vmm,您可能想要評估 vmm_test2 所用時間,該函數在每次調用 rmss 之後才調用。您可能想要評估每個 rmss 所用的時間。

#! 

/usr/bin/ksh
integer i=0
rmss -c 950
while [[ $i -lt 3 ]]
  do
  /tmp/ksh_timer/test_vmm2
  i=i+1
  done
    
rmss -c 1450
i=0
while [[ $i -lt 3 ]]
  do
  /tmp/ksh_timer/test_vmm2
  i=i+1
  done

步驟 1:通過使用適當的 ##KTB 並匹配的 ##KTE,編輯您的 script_test_vmm 腳本和 添加用戶定義部分,從而劃分您的用戶定義部分的界限,如下列代碼所示:

#! 

/usr/bin/ksh
integer i=0
##KTB rmss950
rmss -c 950
while [[ $i -lt 3 ]]
  do
##KTB vmm_test2
  /tmp/ksh_timer/test_vmm2
  i=i+1
##KTE vmm_test2
  done
##KTE rmss950
##KTB rmss1450
rmss -c 1450
i=0
while [[ $i -lt 3 ]]
  do
##KTB vmm_test2
  /tmp/ksh_timer/test_vmm2
  i=i+1
##KTE vmm_test2
  done
##KTE rmss1450

步驟 2:使用 ksh_timer -s script_test_vmm 運行先前的腳本。

-

---------------------Start of script_test_vmm output--------------------------------
Simulated memory size changed to 950 Mb.
Simulated memory size changed to 1450 Mb.
----------------------End of script_test_vmm output--------------------------------
------------------------------------------------------------------------------------------
|    Function   |     Minimum       |     Maximum       | Average    |     Total         |
|               +-------------------+-------------------+------------+-------------------|
|   or Section  |iter.#|   time     |iter.#|   time     |  time      |#iter.|  time      |
|---------------+------+------------+------+------------+------------+------+------------|
|Main           |                                                           |1m36.578814s|
|---------------+------+------------+------+------------+------------+------+------------|
|-rmss950      |     1|1m02.120269s|     1|1m02.120269s|1m02.120269s|     1|1m02.120269s|
|--vmm_test2   |     3|0m16.813174s|     1|0m23.461610s|0m20.654322s|     3|1m01.962968s|
|-rmss1450     |     1|0m34.416279s|     1|0m34.416279s|0m34.416279s|     1|0m34.416279s|
|--vmm_test2   |     2|0m11.382110s|     3|0m11.427596s|0m11.402585s|     3|0m34.207757s|
|---------------+-----------------------------------------------------------+------------|
|-Unaccounted   |                                                           |0m00.042266s|
------------------------------------------------------------------------------------------

查看本欄目更多精彩內容:http://www.bianceng.cn/OS/unix/

作為另一個示例,我們在 mksysb 腳本上運行 ksh_timer。通過編輯 mksysb 腳本,可以添加 一個名為 backup_files_in_list 的用戶定義部分。在以下輸出中我們可以看到,不僅僅對 backup_files_in_list 部分進行計時,而且對在腳本中定義的任何部分都進行了計時。通過查看輸出, 我們很容易發現,mksysb 腳本所用的最大時間在 backup_files_in_list 中,耗時 1m33.029798s,整個 腳本耗時 1m49.140307s。

# ksh_timer -s ./mksysb -i /dev/null
----------------------Start of mksysb output--------------------------------
Creating information file (/image.data) for rootvg.
Creating list of files to back up
Backing up 56510 files........
56510 of 56510 files backed up (100%)0512-038 mksysb: Backup Completed Successfully.
----------------------End of mksysb output--------------------------------
------------------------------------------------------------------------------------------
|    Function   |    Minimum        |    Maximum        |    Average |     Total         |
|               +-------------------+-------------------+------------+-------------------|
|   or Section  |iter.#|  time      |iter.#|  time      |  time      |#iter.|  time      |
|---------------+------+------------+------+------------+------------+------+------------|
|Main           |                                                           |1m49.140307s|
|---------------+------+------------+------+------------+------------+------+------------|
|-set_up_environ|     1|0m00.048720s|     1|0m00.048720s|0m00.048720s|     1|0m00.048720s|
|--fail_if_wpar |     1|0m00.005507s|     1|0m00.005507s|0m00.005507s|     1|0m00.005507s|
|--getoptions   |     1|0m00.012926s|     1|0m00.012926s|0m00.012926s|     1|0m00.012926s|
|-create_temp_di|     1|0m00.007239s|     1|0m00.007239s|0m00.007239s|     1|0m00.007239s|
|-if_rootvg     |     1|0m00.153775s|     1|0m00.153775s|0m00.153775s|     1|0m00.153775s|
|--tddupdate    |     1|0m00.070964s|     1|0m00.070964s|0m00.070964s|     1|0m00.070964s|
|--Get_Rootvg_IS|     1|0m00.042464s|     1|0m00.042464s|0m00.042464s|     1|0m00.042464s|
|--tsddupdate   |     1|0m00.027835s|     1|0m00.027835s|0m00.027835s|     1|0m00.027835s|
|-if_device     |     1|0m00.014855s|     1|0m00.014855s|0m00.014855s|     1|0m00.014855s|
|-if_image_data |     1|0m05.132797s|     1|0m05.132797s|0m05.132797s|     1|0m05.132797s|
|-make_backup_da|     1|0m00.350696s|     1|0m00.350696s|0m00.350696s|     1|0m00.350696s|
|--get_backup_si|     1|0m00.031814s|     1|0m00.031814s|0m00.031814s|     1|0m00.031814s|
|---get_stanza_d|     1|0m00.019862s|     1|0m00.019862s|0m00.019862s|     1|0m00.019862s|
|-run_the_exclud|     1|0m05.697004s|     1|0m05.697004s|0m05.697004s|     1|0m05.697004s|
|-backup_files|     1|1m33.029798s|     1|1m33.029798s|1m33.029798s|     1|1m33.029798s|
|--kill_pid     |     1|0m02.015270s|     2|0m02.020543s|0m02.017906s|     2|0m04.035813s|
|-done_backup   |     1|0m00.016388s|     1|0m00.016388s|0m00.016388s|     1|0m00.016388s|
|--kill_pid     |     1|0m02.015329s|     1|0m02.015329s|0m02.015329s|     1|0m02.015329s|
|---------------------------------------------------------------------------+------------|
|-Unaccounted   |                                                           |0m04.689035s|
------------------------------------------------------------------------------------------

使用第 2 個示例,您也可以輕松地發現是否重復調用了一個函數或某個 部分,或者是否有些調用比其他調用更加耗時。例如,在這裡您可以看出,setcmd 在 init_pos_cmds 中 調用了 44 次,我們還可以看出,最大時間、最小時間和平均時間基本上都是常量。

第 3 個示例使用了 ksh_timer –s ./rpm_share –i 結果,該示例展示了 ksh_timer 中縮進的使 用,以及可在輸出中找到的各種信息。例如,我們可以發現:

在其他兩個函數中也調用了 setcmd :在 init_pos_cmd 中調用了 44 次,在 init_sys_vars 中調用了 5 次。

查看最 小時間、最大時間和平均時間,我們可以看到,不同 setcmd 迭代之間沒有太大差量,不管是在 init_pos_cmd 調用還是從 init_sys_vars 調用。

# ksh_timer –s ./rpm_share –i …
-----------------Start of rpm_share output--------------------------------
-----------------End of rpm_share output--------------------------------
------------------------------------------------------------------------------------------
|    Function   |    Minimum        |     Maximum       |  Average   |       Total       |
|               +-------------------+-------------------+------------+-------------------|
|   or Section  |iter.#|  time      |iter.#|  time      |  time      |#iter.|  time      |
|---------------+------+------------+------+------------+------------+------+------------|
|Main           |                                                           |0m01.506875s|
|---------------+------+------------+------+------------+------------+------+------------|
|-init_baselib  |     1|0m00.366488s|     1|0m00.366488s|0m00.366488s|     1|0m00.366488s|
|--init_pos_cmd |     1|0m00.252172s|     1|0m00.252172s|0m00.252172s|     1|0m00.252172s|
|---setcmd    |    9|0m00.002762s|  5|0m00.002922s|0m00.002825s|44|0m00.124313s|
|--init_sys_vars|     1|0m00.056660s|     1|0m00.056660s|0m00.056660s|     1|0m00.056660s|
|---setcmd    |    5|0m00.002860s|  2|0m00.002929s|0m00.002879s| 5|0m00.014397s|
|---init_libinst|     1|0m00.014667s|     1|0m00.014667s|0m00.014667s|     1|0m00.014667s|
|----inc        |     1|0m00.008601s|     1|0m00.008601s|0m00.008601s|     1|0m00.008601s|
|-----isnum     |     1|0m00.002853s|     1|0m00.002853s|0m00.002853s|     1|0m00.002853s|
|--ck_exp_fs    |     1|0m00.035973s|     1|0m00.035973s|0m00.035973s|     1|0m00.035973s|
|---isYorN      |     1|0m00.002837s|     1|0m00.002837s|0m00.002837s|     1|0m00.002837s|
|---whichfs     |     1|0m00.004191s|     1|0m00.004191s|0m00.004191s|     1|0m00.004191s|
|---getfsfree   |     1|0m00.009434s|     1|0m00.009434s|0m00.009434s|     1|0m00.009434s|
|----isnum      |     1|0m00.002462s|     1|0m00.002462s|0m00.002462s|     1|0m00.002462s|
|---isnum       |     1|0m00.002952s|     1|0m00.002952s|0m00.002952s|     1|0m00.002952s|
|--check_dir    |     1|0m00.002905s|     1|0m00.002905s|0m00.002905s|     1|0m00.002905s|
|-ck_exp_fs     |     1|0m00.036059s|     2|0m00.036169s|0m00.036114s|     2|0m00.072228s|
|--isYorN       |     2|0m00.002875s|     1|0m00.002881s|0m00.002878s|     2|0m00.005756s|
|--whichfs      |     2|0m00.004239s|     1|0m00.004263s|0m00.004251s|     2|0m00.008502s|
|--getfsfree    |     1|0m00.009377s|     2|0m00.009382s|0m00.009379s|     2|0m00.018759s|
|---isnum       |     2|0m00.002425s|     1|0m00.002444s|0m00.002434s|     2|0m00.004869s|
|--isnum        |     2|0m00.003008s|     1|0m00.003030s|0m00.003019s|     2|0m00.006038s|
|-set_time_token|     1|0m00.009403s|     1|0m00.009403s|0m00.009403s|     1|0m00.009403s|
…snip…
|--check_fdup_sp|     1|0m00.098203s|     1|0m00.098203s|0m00.098203s|     1|0m00.098203s|
|---getfsize    |     1|0m00.018850s|     1|0m00.018850s|0m00.018850s|     1|0m00.018850s|
|----check_file |     1|0m00.002347s|     1|0m00.002347s|0m00.002347s|     1|0m00.002347s|
|----isnum      |     1|0m00.002366s|     1|0m00.002366s|0m00.002366s|     1|0m00.002366s|
|---whichfs     |     1|0m00.004378s|     1|0m00.004378s|0m00.004378s|     1|0m00.004378s|
|---addbuf      |     1|0m00.021044s|     1|0m00.021044s|0m00.021044s|     1|0m00.021044s|
|----isnum      |     3|0m00.002948s|     2|0m00.002962s|0m00.002956s|     3|0m00.008868s|
|---ck_exp_fs   |     1|0m00.036967s|     1|0m00.036967s|0m00.036967s|     1|0m00.036967s|
|----isYorN     |     1|0m00.002998s|     1|0m00.002998s|0m00.002998s|     1|0m00.002998s|
|----whichfs    |     1|0m00.004340s|     1|0m00.004340s|0m00.004340s|     1|0m00.004340s|
|----getfsfree  |     1|0m00.009691s|     1|0m00.009691s|0m00.009691s|     1|0m00.009691s|
|-----isnum     |     1|0m00.002514s|     1|0m00.002514s|0m00.002514s|     1|0m00.002514s|
|----isnum      |     1|0m00.002964s|     1|0m00.002964s|0m00.002964s|     1|0m00.002964s|
|--cleanup      |     2|0m00.002960s|     1|0m00.007511s|0m00.005235s|     2|0m00.010471s|
|---------------------------------------------------------------------------+------------|
|-Unaccounted   |                                                           |0m00.141934s|
------------------------------------------------------------------------------------------

故障排除

如果在使用 ksh_timer 工具是發現任何的問題,那麼需要運行:

./ksh_timer –D –c –s <your_script> <script.debug.out 2>&1

將下列文件發送給代碼作者:

script.debug.out

<your_script>

csv 文件 :ksh_timer. <your_script>.<pid>.out

結束語

ksh_timer 是一個簡單而又 方便的可定制工具,可用於估計腳本所用的時間。不需要修改腳本,只需運行一次,就可以了解該腳本最 耗時的函數。如果腳本沒有使用函數,或者大部分時間被該腳本的主部分占用,那麼用戶可以編輯該腳本 ,並在主要部分、甚至是函數中創建用戶定義部分,以便跟蹤耗時最多的某一行的詳細信息。ksh_timer 輸出分析可在耗時最多的用戶 shell 腳本中顯示部分代碼。如果該腳本其中一部分運行了另一個 shell 腳本,那麼用戶可能需要更改這些代碼,以便調用該腳本,使用 ksh_timer 對其進行計時。如果調用的 可執行文件不是一個 shell 腳本,那麼用戶需要使用其他可執行工具對其進行計時。

下載

描述 名字 大小 下載方法 ksh_timer 工具 ksh_timer.tar 30 KB HTTP
Copyright © Linux教程網 All Rights Reserved