Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 相关变量和操作的分组?_C_Performance_Grouping_Code Complete - Fatal编程技术网

C 相关变量和操作的分组?

C 相关变量和操作的分组?,c,performance,grouping,code-complete,C,Performance,Grouping,Code Complete,在《代码完成》第10章中,建议对相关语句进行分组,并给出以下示例: void SummarizeData(...) { ... GetOldData( oldData, &numOldData ); GetNewData( newData, &numNewData ); totalOldData = Sum( oldData, numOldData ); totalNewData = Sum( newData, numNewData );

在《代码完成》第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();
    ...
}
每次操作都必须打开和关闭连接。这似乎是浪费,但我不知道它在实践中如何影响性能


很抱歉,这个问题太长了……

我还没有读完《代码全集》第10章(再过几个晚上就可以了!),但我认为这里的要点是以逻辑和易于阅读的方式对代码行进行分组,而不影响程序功能。换言之,尽可能地清理和重新安排,但一旦它开始真正影响行为,就停止


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

我很无聊,所以我尝试使用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()
现在,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()

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
因此,它起到了作用,尽管可以忽略不计

就在这里


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

谢谢你的指点。《代码完成》有很多信息需要考虑,但是,与其他任何东西一样,您仍然不能将其视为表面价值。