优雅与性能:何时使用冗余列表进行查询?

时间:2012-03-27 21:20:31

标签: python sql performance oop styles

编辑: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

1 个答案:

答案 0 :(得分:1)

基本上,这取决于你需要一个特定事物的频率与你需要它的频率。

如果 提前计算。

另一方面,如果这只是您正在进行的许多查询中的一项,那么使用大量预先计算的东西来混淆数据模型就不那么有意义了;保持模型简单,计算+缓存您需要的内容将使您的代码更容易使用。

只针对性能进行优化,需要以优化性能,如果这样做会以可维护性/编码时间为代价。(请参阅http://c2.com/cgi/wiki?PrematureOptimization 。)