编辑:When should and shouldn't you break away from OOP for speed/performance?可能与此问题相关。
如果我的问题不清楚,我很抱歉;我是业余爱好者,如果我受过更好的教育,我可能会知道一些相关的术语更具体。请允许我使用一些简单的示例代码。
class EmployeeRecords(object):
"""A record of all employees."""
def __init__(self):
super().__init__()
self.employees = []
# The following two attributes are redundant.
self.at_office = {"LAN":[], "DET":[], "KAL":[]}
self.in_thirties = []
def register_employee(self, employee):
"""Register a new employee in the records.
This entire method is redundant.
"""
self.employees.append(employee)
self.at_office[employee.office_code].append(employee)
if 30 <= employee.age < 40:
self.in_thirties.append(employee)
class Employee(object):
"""An employee record featuring relevant information for queries."""
def __init__(self, first_name, last_name, age, office_code):
super().__init__()
self.first_name = first_name
self.last_name = last_name
self.age = age
self.office_code = office_code
# Instantiation and what-not goes here.
...
print([x for x in my_records.employees if 30 <= x.age < 40])
# VS
print(my_records.in_thirties)
哪个更合适?后一种方法通常被专家认为是不良形式的SO?
- 更多信息 -
在EmployeeRecords中注册时,将Employee实例添加到相关列表似乎在计算上更有效。然而,我最近一直在研究SQL(最后),似乎有效使用它的很大一部分是“数据规范化”:从多个表中删除冗余数据,否则可以通过更深层次的查询来实现。
我可以看到并且同意拥有冗余数据可以引发错误;当我的查询可以通过对象(或者在SQL的情况下,表)关联从单个列表中提取时,为什么还要更新所有这些冗余列表呢?在上面的示例中,列表推导将始终返回正确的信息,但如果我愚蠢地添加my_records.in_thirties
而不是使用my_records.employees
,则使用my_records.register_employee
会产生意外结果。
这只是一个例子,在代码管理和性能方面,两种方法之间没有什么区别。但实际上,查询可能涉及搜索对象列表中的列表,这些对象的属性是需要查询其他对象的列表。
为此目的避免冗余列表是否被视为良好做法,或者大多数人认为有利于反复进行非常深入的搜索?我知道Python不是SQL,但我认为OOP通过使用属性非常关注对象之间的关系,因此我可以看到这些类型的列表将被视为错误形式并容易出错。
感谢您的帮助。我没有受过正规教育,虽然我有多年的宠物项目编程经验,但我总是以有效的架构方式学习新事物。经过多年的浏览,这是我在SO上的第一篇文章,所以如果这是一个愚蠢或不恰当的问题,请保持温和。我不知道还能转向哪里!
-David Hernandez
答案 0 :(得分:1)
基本上,这取决于你需要一个特定事物的频率与你需要它的频率。
如果 提前计算。
另一方面,如果这只是您正在进行的许多查询中的一项,那么使用大量预先计算的东西来混淆数据模型就不那么有意义了;保持模型简单,计算+缓存您需要的内容将使您的代码更容易使用。
只针对性能进行优化,需要以优化性能,如果这样做会以可维护性/编码时间为代价。(请参阅http://c2.com/cgi/wiki?PrematureOptimization 。)