简体   繁体   English

相关变量和操作的分组?

[英]Grouping of related variables and operations?

In Code Complete, chapter 10, it is advised to group related statements, and the following example is given: 在“代码完成”的第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 );
    ...
}

It is stated that such grouping and concurrent processing is bad design, and instead gives something more separated: 据说这种分组和并发处理是不好的设计,而是给了一些更分离的东西:

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 );
    ...
}

I do agree that the second approach is easier to read and to understand, and offers cleaner-looking code, at least from my own perspective. 我确实同意,至少从我自己的角度来看,第二种方法更易于阅读和理解,并提供了更简洁的代码。 So, my question is, are there any disadvantages with the second approach? 因此,我的问题是,第二种方法是否有缺点? For example, one possible issue that I could think of is with temporary connections to databases and such: 例如,我想到的一个可能的问题是与数据库的临时连接,例如:

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

This first approach would complete both save operations in one open/close cycle. 第一种方法将在一个打开/关闭周期中完成两个保存操作。 However, with the second approach... 但是,使用第二种方法...

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

You have to open and close the connection for each operation. 您必须打开和关闭每个操作的连接。 This seems wasteful, but I have no idea how it affects performance in practice. 这似乎很浪费,但是我不知道它如何影响实践中的性能。

Sorry for the unnecessarily long question... 抱歉,这个不必要的冗长问题...

I haven't gotten to Chapter 10 in Code Complete just yet (a few more evenings ought to do it!) but I think the main point here is to group your lines of code in a logical and easily readable way, without affecting program functionality. 我还没有进入“代码完成”的第10章(还需要几个晚上!),但我认为这里的重点是以一种逻辑易读的方式对代码行进行分组, 而不影响程序功能。 In other words, clean it up and rearrange it as much as possible, but stop as soon as it starts to actually affect behaviour. 换句话说,请清理并尽可能重新排列它,但只要它开始真正影响行为,就应立即停止。

In your example, we should keep in mind that "Premature optimization is the root of all evil," but I think we can still safely assume that you shouldn't be closing the connection if you're about to open it again right away again, since those two actions literally cancel each other out. 在您的示例中,我们应该牢记“过早的优化是万恶之源”,但是我认为我们仍然可以安全地假设如果您要立即再次打开连接,则不应该关闭连接。 ,因为这两个动作实际上相互抵消了。 As a general rule, any connections should be opened only right before the first time you need them, and closed immediately after the last time they're used, for simplicity's sake. 通常,为简单起见,任何连接都应仅在您第一次需要它们之前打开,并在最后一次使用它们之后立即关闭。

I was bored, so I tried doing a proof-of-concept speed test in Python using Sqlite (which I realize is not the best way to do it). 我很无聊,所以我尝试使用Sqlite在Python中进行概念验证速度测试(我意识到这不是最好的方法)。

First, the base test of 50,000 iterations, opening and closing the connection after every iteration. 首先,进行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()

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()

And now, 50,000 iterations, but without closing the connection. 现在,进行了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()

The results? 结果?

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

So, it makes a difference, albeit a negligible one. 因此,尽管有微不足道的影响,但它有所作为。

And there you have it. 那里有它。

Definitely agree with what Stephane said, though. 不过,我完全同意斯蒂芬妮的话。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM