[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
デコレータで実行時間を測る例のやつ (笑) を色々試してて気になった点や欲しい機能とかをいじってたらなんか後々使えそうな代物ができたので、docstring の書き方の練習も兼ねて公開してみることに。
sp = SimpleProfiler() とかして、
with sp:
pass
とするか、
@sp.profile
def foo():
pass
とすれば sp に測った実行時間やらカウントやらが記録されます。sp の各プロパティを読んで下さい。reset() で測った記録をリセットできます。使いたいという奇特な方は下記をコピペして simpleprofiler.py とかで各自保管して下さい。MITライセンスで扱って貰えば特に連絡などは要りません。
#!/usr/bin/env python3
# simpleprofiler.py - Simple profiler
#
# Copyright (c) 2019 Takayuki 'January June' Suwa
#
# This software is released under the MIT License.
# https://opensource.org/licenses/mit-license.php
# PEP 8 (for lexical)
#000000001111111111222222222233333333334444444444555555555566666666667777777777
#234567890123456789012345678901234567890123456789012345678901234567890123456789
# PEP 8 (for text)
#00000000111111111122222222223333333333444444444455555555556666666666777
#23456789012345678901234567890123456789012345678901234567890123456789012
"""Simple profiler."""
try:
from time import perf_counter_ns as _perf_counter_ns
_clock = lambda: _perf_counter_ns() * 1e-9
except ImportError:
try:
from time import perf_counter as _clock
except ImportError:
from time import clock as _clock
class SimpleProfiler(object):
"""Simple profiler implementation, as context mananger."""
__slots__ = "__started", "__elapsed_time", "__nested_level", \
"__entered_count", "__checked_count", "__raised_count", \
"__clicked_count"
def __init__(self):
self.__started, self.__elapsed_time, self.__nested_level, \
self.__entered_count, self.__checked_count, \
self.__raised_count, self.__clicked_count = 0.0, 0.0, 0, 0, 0,\
0, 0
def __repr__(self):
return "%s(%fsec, %d, %d, %d, %d)" % (self.__class__.__name__,
self.__elapsed_time, self.__entered_count, self.__checked_count,
self.__raised_count, self.__clicked_count)
@property
def elapsed_time(self):
"""Return the accumulated value of the elapsed time in second
around the region of the code, inside of this context.
"""
return self.__elapsed_time
@property
def entered_count(self):
"""Return the accumulated value of the counter which is
incremented by 1 when this context is entered.
"""
return self.__entered_count
@property
def checked_count(self):
"""Return the accumulated value of the counter which is
incremented by 1 when each time check has finished.
"""
return self.__checked_count
@property
def raised_count(self):
"""Return the accumulated value of the counter which is
incremented by 1 when each uncaught exception has been raised.
"""
return self.__raised_count
@property
def clicked_count(self):
"""Return the accumulated value of the counter which is
incremented by 1 when each 'click()' method has been called.
"""
return self.__clicked_count
def click(self):
"""Increment the number of times this method was called, by 1.
"""
self.__clicked_count += 1
def reset(self):
"""Reset the elapsed time and each counters, to the initial
state.
"""
self.__elapsed_time, self.__nested_level, self.__entered_count, \
self.__checked_count, self.__raised_count, \
self.__clicked_count = 0.0, 0, 0, 0, 0, 0
def __enter__(self):
"""Enter this context.
When re-entered an identical context, results of that time check
and counting are ignored.
"""
self.__entered_count += 1
self.__nested_level += 1
if self.__nested_level == 1:
self.__started = _clock()
def __exit__(self, exc_type, exc_val, exc_tb):
"""Exit from this context."""
if self.__nested_level == 1:
self.__elapsed_time += _clock() - self.__started
self.__checked_count += 1
if exc_type:
self.__raised_count += 1
self.__nested_level -= 1
def profile(self, func):
"""Decorate the below function as inside of this context."""
def wrapper(*args, **kwargs):
with self:
return func(*args, **kwargs)
return wrapper
if __name__ == "__main__":
print("\n[ SimpleProfiler demo ] Profiles the Fibonacci function!\n")
p = SimpleProfiler()
@p.profile
def fib(x):
return x if x < 2 else fib(x - 1) + fib(x - 2)
def fib_demo():
p.reset()
try:
for n in range(40):
p.reset()
print(" profiling fib(%d) in progress..."
% n, end="", flush=True)
print("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b=%d, %f seconds elapsed\n"
" %d entered, %d checked, %d raised"
% (fib(n), p.elapsed_time, p.entered_count, \
p.checked_count, p.raised_count))
except KeyboardInterrupt:
print("\n***** aborted by user *****\n"
" %f seconds elapsed (until abort)\n"
" %d entered, %d checked, %d raised"
% (p.elapsed_time, p.entered_count, p.checked_count,
p.raised_count))
print("[normal (uncached) version]")
fib_demo()
from functools import lru_cache
@p.profile
@lru_cache()
def fib(x):
return x if x < 2 else fib(x - 1) + fib(x - 2)
print("\n[cached version]")
fib_demo()今更シリーズの第3!弾、さて今回は往年の組み込み用 CPU、日立 H8/300 用の GCC などは如何でしょうか。ルネサスさん、なんと一部品番については 2020 年代中頃辺りまで供給するつもりらしいです。
秋月でもまだまだ扱いがあるあたり、根強い需要があるのか、それとも余程在庫が残ってるのか…
妙な邪推はさておき、x86 な Windows で動作する最新(本稿執筆時)の H8/300 用ビルド済み
を公開しておきます。
MSYS2 32bit 環境下でビルドしてありますが、利用に MSYS2 や他のライブラリの類のインストールは必要ありません。詳しくは同梱の readme.txt とかを見て下さい。
gcc-8.3.0_h8300-hitachi-elf_Windows.7z (SHA-1: 22a9f12535959354877ecac1e77fb94c3108653b)
同梱の Windows インストーラー(*.msi) を使えば直ちにインストールできます。確認とか全く聞いてこない手抜き仕様なので注意。
アンインストールも Windows インストーラーなので簡単。
もう平成も終わろうというのに、今さら玄箱(初代)に Debian Jessie (archive) を debootstrap して linux-4.4.229 を添えてみました。
# /etc/fstab proc /proc proc defaults 0 0 /dev/sda3 / ext4 defaults,noatime 0 1 /dev/sda1 /boot ext2 defaults,noatime 0 2 /dev/sda2 swap swap defaults 0 0これは玄箱(初代)本来の割り方ではなく、他所の野良 linux 化でよくされていた割り方とも微妙に違うので、U-Boot 変数の設定とかを引き写してくる際には注意
kuroboxHDkuroboxHD.local)、および ssh が有効root へログイン可能、パスワードは kuroboxHDapt-get して下さい今更 SuperH かよ、とも思ったがルネサスさんまだ製品展開頑張ってるんですね…
(最大クロック増加・2ウェイスーパースケーラ化・割り込み応答速度向上など)
FA SBC にも結構使われているようで秋月にも SH2A 基板が出てくるあたり、それなりに力を入れているのかも。あと所用でその SH2A な FA SBC を評価することになったので、GCC ビルドすっか、というお話。
それで、以前の投稿ではここからビルド手順が書いてあったのですが、ややこしいのでばっさり割愛。x86 な Windows で動作する最新(本稿執筆時)の SuperH 用ビルド済み
を公開しておきます。
MSYS2 32bit 環境下でビルドしてありますが、利用に MSYS2 や他のライブラリの類のインストールは必要ありません。詳しくは同梱の readme.txt とかを見て下さい。
gcc-8.3.0_sh-renesas-elf_Windows.7z (SHA-1: 985d36941f4a47708ce50985b4412958c4b7ec05)
同梱の Windows インストーラー(*.msi) を使えば直ちにインストールできます。確認とか全く聞いてこない手抜き仕様なので注意。
アンインストールも Windows インストーラーなので簡単。

カレンダー
フリーエリア
最新コメント
最新記事
プロフィール
ブログ内検索
最古記事
P R