基本指令数及其类型

时间:2019-05-03 18:28:09

标签: python-3.x

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

我想知道是否可以在python上做(如果可以,怎么办?还没有发现任何东西)


我知道有一个时间功能可以测量运行代码所需的时间,但是我的PC和计划使用的控制器的计算能力并不相同。

我也尝试自己计算一下,但这很痛苦并且容易出错


理想的结果将是:

  • 使用INT的基本算术运算的X数
  • 使用FLOAT的基本算术运算的Y次数
  • Z二进制操作

等...

谢谢

1 个答案:

答案 0 :(得分:0)

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

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