Python中如何求平均运行时间

如题,log 类似下面这样

get_foo start 913912131
get_foo end 14141251132
get_abc start 12312415
get_def start 123156151
get_def end 123115112312
get_abc end 121515161

第一列是线程名,最后一列是线程运行时间 怎么求同名线程的平均运行时间?


Python中如何求平均运行时间
21 回复

给个 lock 让主线程去算啊


import time
import statistics

def measure_average_runtime(func, *args, iterations=1000, **kwargs):
    """
    测量函数平均运行时间
    
    Args:
        func: 要测试的函数
        *args: 函数的位置参数
        iterations: 测试迭代次数,默认为1000次
        **kwargs: 函数的关键字参数
    
    Returns:
        tuple: (平均运行时间(秒), 所有运行时间列表)
    """
    run_times = []
    
    for _ in range(iterations):
        start_time = time.perf_counter()  # 使用高精度计时器
        func(*args, **kwargs)
        end_time = time.perf_counter()
        run_times.append(end_time - start_time)
    
    # 计算统计信息
    avg_time = statistics.mean(run_times)
    min_time = min(run_times)
    max_time = max(run_times)
    std_dev = statistics.stdev(run_times) if len(run_times) > 1 else 0
    
    return avg_time, run_times, {
        'min': min_time,
        'max': max_time,
        'std_dev': std_dev,
        'iterations': iterations
    }

# 使用示例
def example_function(n):
    """示例函数:计算0到n-1的和"""
    total = 0
    for i in range(n):
        total += i
    return total

if __name__ == "__main__":
    # 测试example_function(1000)的平均运行时间
    avg_time, all_times, stats = measure_average_runtime(
        example_function, 
        1000, 
        iterations=100
    )
    
    print(f"平均运行时间: {avg_time:.8f} 秒")
    print(f"最短时间: {stats['min']:.8f} 秒")
    print(f"最长时间: {stats['max']:.8f} 秒")
    print(f"标准差: {stats['std_dev']:.8f} 秒")
    print(f"测试次数: {stats['iterations']} 次")
    
    # 如果需要更详细的统计,可以使用statistics模块
    print(f"\n详细统计:")
    print(f"中位数: {statistics.median(all_times):.8f} 秒")
    print(f"第95百分位数: {statistics.quantiles(all_times, n=20)[18]:.8f} 秒")

核心要点:

  1. 使用time.perf_counter()获取高精度时间戳
  2. 多次运行取平均值以减少误差
  3. 使用statistics模块进行统计分析
  4. 考虑使用timeit模块作为替代方案

一句话建议: 多次测量取平均,用perf_counter提高精度。

python 练习题……就是分析日志

这……怎么平均

我的理解是,首先筛选第一列相同的 get_foo,然后就一行 end 的第三列减去一行 start 的第三列。就是一次执行时间,然后把文件中所有 get_foo 的执行时间求和,除以执行次数

但是线程名都不相同…而且都只运行了一次 emmm 不懂

人家总不能贴个几万行的日志上论坛吧……

这只是日志格式。。。不能贴几百行上来啊。。难点就是线程名不同,要先根据线程名筛选,然后再根据 start end 筛选。
我目前想法是,用多个 list 来实现,但是感觉太笨重了。。



2333 确实有些误解了

塞到 map 里

用一个 namedtuple 和一个 dict 就可以了吧
统计值放到 tuple namedtuple(‘LogStatistic’, [‘已经统计的线程数’, ‘统计过的线程的时间’])

用一个 dict 保存线程的开始时间 {‘get_foo’: {start: 913912131}, ‘get_abc’: {start: 12312415}} 用来保存时间,每读取到数据看看是否 start 和 end 都有了,有的话从 dict 中删除这个键,统计进入 tuple

用到了 python pandas 包

df = pd.read_clipboard(header=None)

df.columns = [‘process’,‘status’,‘time’]

df.groupby(by=‘process’).apply(lambda x:(x.sort_values(by=‘time’).loc[x.status==‘end’,‘time’].values - - x.sort_values(by=‘time’).loc[x.status==‘start’,‘time’].values).mean())


前提是要保证线程的 start 和 end 的数量是匹配的

写完上面我又想到一个更好的办法,透视表
df_pivot = df.pivot_table( values=‘time’, index=‘process’,columns=‘status’,aggfunc=list)

df_pivot.apply(lambda x:(pd.np.array(sorted(x.end)) - pd.np.array(sorted(x.start))).mean(), axis=1)

首先楼主的问题没有描述清楚,给的信息不够,如同名线程中后面的线程比前面的先结束,如何正确配对开始和结束时间?
另外,说心理话这么简单个问题都要到这里来问,劝退。楼主你不是干这行的料。

用 pandas 实现很简单,但是最好使用自带的函数解决。。。下面的不错,不过我 pivot 一点没看。。。但是表示感谢。。。。

原始的题目就是这样的,应该是同名的前面的总是比后面的先结束。
我本来就不是码农,闲的没事学 python,我这才看了 3 天,有问题还不能问了? 看了下你的回帖,总是对提问人各种嘲讽。难道你是什么都知道?呵呵

那也简单啊,建个 defaultdict ( list ),key 是( process,status ),value 是[time],然后相减,其实就是一个 group by 操作

,我这么说你肯定不服气,下面用你能理解的方式写了一个算法。

#!/usr/bin/env python
# -- coding: utf-8 --

data = “”“get_foo start 913912131
get_foo end 14141251132
get_abc start 12312415
get_def start 123156151
get_def end 123115112312
get_abc end 121515161
get_foo start 913912131
get_foo end 14141251132
get_abc start 12312415
get_def start 123156151
get_def end 123115112312
get_abc end 121515161
get_foo start 913912131
get_foo end 14141251132
get_abc start 12312415
get_def start 123156151
get_def end 123115112312
get_abc end 121515161
"”"

i_data = (l.split() for l in data.splitlines())

result={}
for proc, flag, timestamp in i_data:
□□□□temp = result.setdefault(proc, {‘sum’:0,‘cnt’:0, ‘start’:0})
□□□□if flag == ‘start’:
□□□□□□□□temp[‘start’]=int(timestamp)
□□□□else:
□□□□□□□□temp[‘sum’] += int(timestamp) - temp[‘start’]
□□□□□□□□temp[‘cnt’] += 1

for p, v in result.items():
□□□□print(‘process:’, p, ‘avg time:’,v[‘sum’]/v[‘cnt’])

最暴力的做法
线程名做 key,总时间和运行次数组成一个 tuple 做 value
遍历一遍日志全塞到一个 dict 里
最后遍历一遍 dict 把每个线程的平均时间求出来

用比较笨的方法实现了一下

with open(‘logtest.txt’,‘r’,encoding=‘utf-8’) as f:
list=[]
for lines in f:
list.append(lines.split())

api_name={}
count={}
for i in list:
if i[0] not in api_name:
api_name.update({i[0]:(0-int(i[2]))})
count.update({i[0]:int(“1”)})
else:
if i[1] ==“end”:
api_name.update({i[0]:(int(i[2])+int(api_name[i[0]]))})
count.update({i[0]:(count[i[0]]+1)})
if i[1] == “start”:
api_name.update({i[0]:(int(api_name[i[0]]-int(i[2])))})
count.update({i[0]:(count[i[0]]+1)})

for i in count.keys():
print(‘api’,i,“average running time =”,api_name[i] / count[i])

import sys

d = {}
n = 0
s = 0
for line in sys.stdin:
____name, flag, t = line.split()
____t = int(t)
____if flag == “start”:
________d[name] = t
____elif name in d:
________s += t - d[name]
________n += 1
________del d[name]

print(s / n)

导入 pandas,求出 unique names,然后 reshape(2, N/2), sum(ax=1) -> (start_sum, end_sum) -> (end_sum - start_sum) / N * 2

感谢回复。。。第一次发现 python 居然可以这样赋值。。name, flag, t = line.split()

回到顶部