2017-02-26 8 views
2

私はPythonスクリプトからシステムの稼働時間を読み込むための、高速で軽量な方法を探しています。 Pythonからsysinfo Linuxシステムコールを呼び出す方法はありますか?PythonでLinuxのシステム稼働時間を得る最速の方法

これまでは、稼働時間を測定するための2つの方法、つまり外部プロセスを実行する方法と/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 

速度を比較すると、2番目の方法は約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 
+1

ファイル...彼らは最終的にあなたが得る/異なるものを設定することができますいくつかの他のものにフックアップされています。あなたが望むなら、 '.so'ファイルをPythonで読み込むことができます。 0.03秒/ 1000倍速くはありませんか? – HuStmpHrrr

答えて

4

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 

UPDATE

の時間のほとんどはlibcに引っ張って過ごし、バッファを作成しています。時間の経過とともに繰り返し呼び出しを行う予定がある場合は、そのステップを関数から抜き取り、システムコールだけを測定することができます。その場合には、この解決策は明確な勝者です: `/ procの/`ファイルではありませんで

uptime1: 5.066633300986723 
uptime2: 0.11561189399799332 
uptime3: 0.007740753993857652 
+0

確かに彼らは...ありがとう。しかし、もう一度考えると、最初の1〜2行を関数呼び出しから取り除くことで最適化できると思います。 – kfx

+1

これは私がLIBSを取得し、グローバル変数としてバッファリングするものである:uptime1:1.8627383150014794 uptime2:0.03709090399206616 uptime3:0.0018650189886102453 – kfx

+0

しかし、基本的に、あなたは、PythonからCライブラリ関数を呼び出す方法を示すことによって、私の質問に答えました。 – kfx

4

あなたがしてpsutilをインストールしてみてくださいすることができます

pip install psutil 

、その後、次のコードの断片を使用します。私はあなたが​​を使用するよりもはるかに高速に得ることができるとは思わない

import psutil 
import time 


def seconds_elapsed(): 
    return time.time() - psutil.BOOT_TIME 


print seconds_elapsed() 
+1

私はこれが2に近づくよりはるかに速いことに非常に驚くでしょう:https://github.com/giampaolo/psutil/blob/master/psutil/_pslinux.py#L1255 – HuStmpHrrr

+1

私もそうですが、それは最も速いクロスプラットフォームです。 OPがLinuxを要求してもポータブルなソリューション – JuniorCompressor

+0

この回答は退屈です。それは非常に単純すぎる! ...(冗談)私は言っている:この素敵な答えをありがとう。 – guettli

関連する問題