IT/python

[python3] 셸 명령 파싱하기 성능 비교

심량 2024. 1. 5. 17:54

기존에 파이썬 cpu 온도 얻어오는 코드가 awk 를 두번 돌려서 파싱하는 구조로 되어 있었습니다.

vcgencmd measure_temp 명령 결과를 파이썬에서 파싱해도 되는데 뭐가 성능이 더 좋을까 하는 궁금증이 생겼습니다.

pi@RPwiznet013:~/wiznet/skp_arhis/app $ python3
Python 3.7.3 (default, Jan 22 2021, 20:04:44)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> ret, res = subprocess.getstatusoutput("vcgencmd measure_temp")
>>> res
"temp=56.4'C"
>>> begin = res.find("=")
>>> end = res.find("'")
>>> res[begin:end]
'=56.4'
>>> begin = res.find("=") + 1
>>> res[begin:end]
'56.4'
>>> import timeit
>>> timeit.
timeit.Timer(          timeit.gc              timeit.sys
timeit.default_number  timeit.itertools       timeit.template
timeit.default_repeat  timeit.main(           timeit.time
timeit.default_timer(  timeit.reindent(       timeit.timeit(
timeit.dummy_src_name  timeit.repeat(
>>> def f1():
...     ret, res = subprocess.getstatusoutput("vcgencmd measure_temp")
...     begin = res.find("=") + 1
...     end = res.find("'")
...     return res[begin:end]
...
>>> def f2():
...     ret, res = subprocess.getstatusoutput("""vcgencmd measure_temp | awk -F= '{print $2}' | awk -F"'" '{print $1'""")
...     return res
...
>>> timeit
timeit
>>> timeit.timeit("f1()", number=1000000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.7/timeit.py", line 232, in timeit
    return Timer(stmt, setup, timer, globals).timeit(number)
  File "/usr/lib/python3.7/timeit.py", line 176, in timeit
    timing = self.inner(it, self.timer)
  File "<timeit-src>", line 6, in inner
NameError: name 'f1' is not defined
>>> timeit.timeit("f1()", setup='from __main__ import f1', number=1000000)
^CTraceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.7/timeit.py", line 232, in timeit
    return Timer(stmt, setup, timer, globals).timeit(number)
  File "/usr/lib/python3.7/timeit.py", line 176, in timeit
    timing = self.inner(it, self.timer)
  File "<timeit-src>", line 6, in inner
  File "<stdin>", line 2, in f1
  File "/usr/lib/python3.7/subprocess.py", line 586, in getstatusoutput
    data = check_output(cmd, shell=True, text=True, stderr=STDOUT)
  File "/usr/lib/python3.7/subprocess.py", line 395, in check_output
    **kwargs).stdout
  File "/usr/lib/python3.7/subprocess.py", line 474, in run
    stdout, stderr = process.communicate(input, timeout=timeout)
  File "/usr/lib/python3.7/subprocess.py", line 926, in communicate
    stdout = self.stdout.read()
  File "/usr/lib/python3.7/codecs.py", line 319, in decode
    def decode(self, input, final=False):
KeyboardInterrupt
>>> timeit.timeit("f1()", setup='from __main__ import f1', number=100)
0.7849986139999601
>>> timeit.timeit("f1()", setup='from __main__ import f1', number=100)
0.8233056509998278
>>> timeit.timeit("f1()", setup='from __main__ import f1', number=100)
0.7967234309999185
>>> timeit.timeit("f2()", setup='from __main__ import f2', number=100)
0.9214457070002027
>>> timeit.timeit("f2()", setup='from __main__ import f2', number=100)
0.9458632500000022
>>> timeit.timeit("f2()", setup='from __main__ import f2', number=100)
0.946327673000269

awk 두 번 돌리는 것(f2())보다 파이썬으로 찾는 게 (f1())약간 더 빠르게 나왔네요