在 Linux 中使用 Python 获得系统正常运行时间的最快方法

新手上路,请多包涵

我正在寻找一种快速、轻量级的方法来从 Python 脚本中读取系统正常运行时间。有没有办法从 Python 调用 sysinfo Linux 系统调用?

到目前为止,我发现了另外两种测量正常运行时间的方法,一种涉及运行外部进程,另一种涉及读取 /proc 中的文件。

 import subprocess

def uptime1():
    raw = subprocess.check_output('uptime').decode("utf8").replace(',', '')
    days = int(raw.split()[2])
    if 'min' in raw:
        hours = 0
        minutes = int(raw[4])
    else:
        hours, minutes = map(int,raw.split()[4].split(':'))
    totalsecs = ((days * 24 + hours) * 60 + minutes) * 60
    return totalsecs

def uptime2():
    with open('/proc/uptime', 'r') as f:
        uptime_seconds = float(f.readline().split()[0])
        return uptime_seconds

比较速度时,第二种方法要快 50 倍左右。不过,直接调用系统调用应该再好一个数量级。

 >> import timeit
>> print(timeit.timeit('ut.uptime1()', setup="import uptimecalls as ut", number=1000))
1.7286969429987948
>> print(timeit.timeit('ut.uptime2()', setup="import uptimecalls as ut", number=1000))
0.03355383600865025

原文由 kfx 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 497
2 个回答

我不认为你可以比使用 ctypes 调用 sysinfo() 更快,但在我的测试中,它比 /proc 慢。那些linux系统程序员好像知道自己在做什么!

 import ctypes
import struct

def uptime3():
    libc = ctypes.CDLL('libc.so.6')
    buf = ctypes.create_string_buffer(4096) # generous buffer to hold
                                            # struct sysinfo
    if libc.sysinfo(buf) != 0:
        print('failed')
        return -1

    uptime = struct.unpack_from('@l', buf.raw)[0]
    return uptime

在我的慢速笔记本电脑上运行你的两个测试和我的,我得到:

 >>> print(timeit.timeit('ut.uptime1()', setup="import uptimecalls as ut", number=1000))
5.284219555993332
>>> print(timeit.timeit('ut.uptime2()', setup="import uptimecalls as ut", number=1000))
0.1044210599939106
>>> print(timeit.timeit('ut.uptime3()', setup="import uptimecalls as ut", number=1000))
0.11733305400412064

更新

大部分时间花在拉入 libc 和创建缓冲区上。如果您计划随着时间的推移重复进行调用,那么您可以将这些步骤从函数中提取出来,只测量系统调用。在那种情况下,这个解决方案是明显的赢家:

 uptime1: 5.066633300986723
uptime2: 0.11561189399799332
uptime3: 0.007740753993857652

原文由 tdelaney 发布,翻译遵循 CC BY-SA 3.0 许可协议

坦率地说,这似乎是一个更好的解决方案:

 def get_uptime():
    with open('/proc/uptime', 'r') as f:
        uptime_seconds = float(f.readline().split()[0])

    return uptime_seconds

它还具有不需要任何额外模块的额外好处。

学分: 来源

原文由 vpetersson 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题