0

在 Code Complete 第 10 章中,建议对相关语句进行分组,并给出以下示例:

void SummarizeData(...) {
    ...
    GetOldData( oldData, &numOldData );
    GetNewData( newData, &numNewData );
    totalOldData = Sum( oldData, numOldData );
    totalNewData = Sum( newData, numNewData );
    PrintOldDataSummary( oldData, totalOldData, numOldData );
    PrintNewDataSummary( newData, totalNewData, numNewData );
    SaveOldDataSummary( totalOldData, numOldData );
    SaveNewDataSummary( totalNewData, numNewData );
    ...
}

据说这样的分组和并发处理是不好的设计,而是给出了更分离的东西:

void SummarizeData(...) {
    GetOldData( oldData, &numOldData );
    totalOldData = Sum( oldData, numOldData );
    PrintOldDataSummary( oldData, totalOldData, numOldData );
    SaveOldDataSummary( totalOldData, numOldData );
    ...
    GetNewData( newData, &numNewData );
    totalNewData = Sum( newData, numNewData );
    PrintNewDataSummary( newData, totalNewData, numNewData );
    SaveNewDataSummary( totalNewData, numNewData );
    ...
}

我确实同意第二种方法更容易阅读和理解,并且提供看起来更清晰的代码,至少从我自己的角度来看是这样。所以,我的问题是,第二种方法有什么缺点吗?例如,我能想到的一个可能的问题是与数据库的临时连接等:

void SummarizeData(...) {
    ...
    externalDataStore.open();
    externalDataStore.save(oldData, numOldData);
    externalDataStore.save(newData, numNewData);
    externalDataStore.close();
    ...
}

第一种方法将在一个打开/关闭周期中完成两个保存操作。但是,使用第二种方法...

void SummarizeData(...) {
    ...
    externalDataStore.open();
    externalDataStore.save(oldData, numOldData);
    externalDataStore.close();
    ...
    externalDataStore.open();
    externalDataStore.save(newData, numNewData);
    externalDataStore.close();
    ...
}

您必须为每个操作打开和关闭连接。这似乎很浪费,但我不知道它如何影响实践中的性能。

对不起,不必要的长问题...

4

2 回答 2

1

我还没有读到 Code Complete 的第 10 章(应该再过几个晚上!),但我认为这里的重点是以合乎逻辑且易于阅读的方式对代码行进行分组,而不会影响程序功能. 换句话说,尽可能地清理和重新排列它,但一旦它开始真正影响行为就停止。

在您的示例中,我们应该记住“过早的优化是万恶之源”,但我认为我们仍然可以安全地假设如果您要立即再次打开连接,您不应该关闭连接,因为这两个动作实际上相互抵消了。作为一般规则,为简单起见,任何连接都应仅在您第一次需要它们之前打开,并在最后一次使用它们之后立即关闭。

于 2011-08-26T15:05:58.357 回答
0

我很无聊,所以我尝试使用 Sqlite 在 Python 中进行概念验证速度测试(我意识到这不是最好的方法)。

首先,50000次迭代的基础测试,每次迭代后打开和关闭连接。

#!/usr/bin/env python

import sqlite3

class Creature(object):
    legs = 0

    eyes = 'monocular'

    kind = ''

conn = sqlite3.connect(':memory:')

c = conn.cursor()
c.execute('''create table testtable
        (date text, legs text, eyes text, kind text)''')
conn.commit()
c.close()

for i in range(50000):
    c = conn.cursor()

    creature1 = Creature()
    creature1.legs = 5
    creature1.eyes = 'monocular'
    creature1.kind = 'mungy'
    c.execute('insert into testtable values (?,?,?,?)', ('today', str(creature1.legs), creature1.eyes, creature1.kind))

    creature2 = Creature()
    creature2.legs = 3
    creature2.eyes = 'binocular'
    creature2.kind = 'thingy'
    c.execute('insert into testtable values (?,?,?,?)', ('today', str(creature2.legs), creature2.eyes, creature2.kind))

    creature3 = Creature()
    creature3.legs = 3
    creature3.eyes = 'monocular'
    creature3.kind = 'pungy'    
    c.execute('insert into testtable values (?,?,?,?)', ('today', str(creature3.legs), creature3.eyes, creature3.kind))

    conn.commit()
    c.close()

现在,50,000 次迭代,但没有关闭连接。

#!/usr/bin/env python

import sqlite3

class Creature(object):
    legs = 0

    eyes = 'monocular'

    kind = ''

conn = sqlite3.connect(':memory:')

c = conn.cursor()
c.execute('''create table testtable
        (date text, legs text, eyes text, kind text)''')
conn.commit()
c.close()

c = conn.cursor()
for i in range(50000):

    creature1 = Creature()
    creature1.legs = 5
    creature1.eyes = 'monocular'
    creature1.kind = 'mungy'

    creature2 = Creature()
    creature2.legs = 3
    creature2.eyes = 'binocular'
    creature2.kind = 'thingy'

    creature3 = Creature()
    creature3.legs = 3
    creature3.eyes = 'monocular'
    creature3.kind = 'pungy'

    c.execute('insert into testtable values (?,?,?,?)', ('today', str(creature1.legs), creature1.eyes, creature1.kind))
    c.execute('insert into testtable values (?,?,?,?)', ('today', str(creature2.legs), creature2.eyes, creature2.kind))
    c.execute('insert into testtable values (?,?,?,?)', ('today', str(creature3.legs), creature3.eyes, creature3.kind))

    conn.commit()
c.close()

结果?

First method: Average 2.264s
Second method: Average 2.157s

因此,它有所作为,尽管微不足道。

你有它。

不过,绝对同意斯蒂芬所说的话。

于 2011-09-02T18:08:02.613 回答