首页 > 解决方案 > 统计基本指令的数量及其类型

问题描述

我有一些代码(几百行),我想在一些“真实”控制器上重现代码。我想通过计算有多少指令(基本算术、操作类型(浮点数、二进制等)来预测代码运行需要多长时间。)

我想知道是否可以在 python 上做(如果是的话怎么做?还没有找到任何东西)


我知道有一个时间功能可以测量运行代码需要多长时间,但我的 PC 和我计划使用的控制器的计算能力不一样。

我也试过自己数数,但这很痛苦,而且容易出错


理想的结果是:

ETC ...

谢谢

标签: python-3.x

解决方案


你的问题让我思考。我写了一个小框架来说明你如何实现这样的东西。基本上,您创建自己的数字类和一个集合来保存它们。然后,每次输入这些函数时,您都会覆盖默认运算符并增加一个变量。请注意,这并不可靠。没有错误检查,它假定所有操作都是使用自定义类对象完成的。

from collections import defaultdict # Acts like a dictionary,  but every time you add a key, the value defaults to a specified value

class Collection(object): # Use this to hold your custom types
    def __init__(self):
        self.items = []
        return

    def add_item(self, item):
        self.items.append(item)


class myFloat(object): # Your custom float class
    def __init__(self, val, collection):
        """ val is the value, collection is the Collections object where we will place your object """
        self.val = float(val)
        self.op_counts = defaultdict(int) # a dictionary where values default to an integer, 0.
        collection.add_item(self) # Add this object to the collection

    def __add__(self, other): # Called when you use + on two myFloat
        self.op_counts["+"] += 1 # Adds 1 to the number of "+" used
        return self.val + other.val # returns the result. 

    def __sub__(self, other): # Called when you use - on two myFloat
        self.op_counts["-"] += 1
        return self.val - other.val

    def __mul__(self, other): # Called when you use * on two myFloat
        self.op_counts["*"] += 1
        return self.val * other.val

    def __truediv__(self, other): # Called when you use / on two myFloat
        self.op_counts["/"] += 1
        return self.val / other.val

### EXAMPLE     
import random
ops = ["+", "-", "*", "/"] 
# We should create a separate Collection object for each custom type we have.
# Since we only have myFloat, we make one Collection object to hold the myFloats.

float_collection = Collection()

# This instantiates a myFloat object with val=7.12 and uses your float_collection
y = myFloat(7.12, float_collection) 

for x in range(1, 1000):
    op = random.choice(ops) # Pick a random operation
    xx = myFloat(x, float_collection) # Instantiate another myFloat
    # Now perform the operation on xx and y. eval evaluates the string but
    # opens the door for security holes if you are worried about hackers. CAREFUL.
    eval(f"y{op}xx") # Remove this line and use the one below if your python < 3.6
    # eval("y{}xx".format(op)) 

print("### RESULTS ###")
result_op_counts = defaultdict(int) # We use this to count up our results

# Sorry for the confusing syntax. The items parameter of the Collection object
# is NOT the same as the items() method for dictionaries.

# float_collection.items is a list of your myFloats.
# the items() method for dictionary returns a dict_items object that you can iterate through.
# This loop tallies up all the results
for myFloatObj in float_collection.items: 
    for op, ct in myFloatObj.op_counts.items():
        result_op_counts[op] += ct

# And this loop prints them.
for k,v in result_op_counts.items():
    print(f"{k}: {v} operations") # Remove this line and use the one below if your python < 3.6
    # print("{}: {} operations".format(k, v))

这输出

### RESULTS ###
*: 227 operations
/: 247 operations
+: 275 operations
-: 250 operations

推荐阅读