全局对象与多个新对象?

时间:2011-09-20 10:17:14

标签: c# ms-access object oledb methodology

假设我要在每次运行期间创建一个需要创建少量对象的方法,并且该方法将被多次调用,即从数据库中删除给定行的方法。每次创建一个新对象并最后调用垃圾收集器(或类似的)来销毁它,或者每次重新初始化值是不是更好?

示例:
每次使用新的构造函数:

private void RemoveFolder(string dir)
{
    OleDbCommand cmd2 = connection.CreateCommand();
    OleDbParameter parameterC = new OleDbParameter();
    cmd2.Parameters.Add(parameterC);
    parameterC.Value = dir;

    cmd2.CommandText = "DELETE * FROM [Directories] WHERE Path = ?";
    cmd2.ExecuteNonQuery();
    cmd2.Dispose();
}

使用单数全局变量(在构造函数中初始化):

private void RemoveFolder(string dir)
{
    parameterC.Value = dir;

    cmd2.CommandText = "DELETE * FROM [Directories] WHERE Path = ?";
    cmd2.ExecuteNonQuery();
}

编辑:当我说得更好时,我的意思是" as-a-whole"在正常的非 - "任务关键型"程序,其中性能的大幅提升将优先于稳定性的轻微下降。

EDIT2

多次调用类似方法的示例

(请注意,这是我的另一种方法,AddFolder)

foreach (DirectoryInfo directory in directories)
{
    parameter.Value = directory.FullName;
    cmd.CommandText = "SELECT LastModified FROM Directories WHERE Path = ?";
    reader = cmd.ExecuteReader();

    while (reader.Read())
    {
        output += reader.GetString(0);
    }

    if (output == null)
    {
        Console.WriteLine("New Directory! " + directory.FullName);
        AddFolder(directory);
    }
    output = null;
    reader.Close();
 }

7 个答案:

答案 0 :(得分:3)

您的问题是我是否需要优化该代码?

我的意见一般,

  1. 如果两个很容易优化它,代码仍然比它简单, 否则,如果不确定是否会产生影响而不是那样,
  2. 如果您不确定
  3. ,请进行测量
  4. 在相关代码附近留下评论
  5. 如何衡量? 您可以看到您的程序是否运行缓慢,或者它是否使用了很多内存..

答案 1 :(得分:1)

关于第二次编辑,

您可以将foreach循环转换为LINQ, 聚合所有目录,然后立即聚合 将目录添加到DB

您的代码看起来会更优雅,它将解决您的主要问题

参见http://www.linqtutorial.net/linqExamples.html有段落如何用LINQ替换迭代循环

答案 2 :(得分:1)

您在此处遇到的主要问题是您为查询的“准备”支付了多少费用。准备是查询被解析的地方,并且(更重要的是)确定查询计划。查询计划的确定可能相当昂贵,并且您希望最少这么多次

(注意:您的示例中的偶DELETE ... WHERE ...需要一个查询计划。)

在“重用”查询计划中,某些DBMS和ADO.NET提供程序比其他提供程序更好。例如,在Oracle / ODP.NET上,如果您反复重新创建DbCommand,则可能无关紧要 - Oracle将倾向于“看到”这是之前使用过的查询并重用查询计划。

另一方面,如果你想确保查询准备一次并重复使用多次,无论你使用什么DBMS,保持相同{{1}都不是一个坏主意。整个应用程序执行期间的对象(甚至显式调用DbCommand),如下所示:

DbCommand.Prepare

所以:

  • 如果您的程序仅适用于单个DBMS / ADO.NET提供程序,并且您知道它将有效地重用查询计划,并且您不介意稍微昂贵的C#代码,那么您可以选择“重复重新创建”解决方案。它也可能允许稍微缩短的C#代码。
  • 但是,我更喜欢“一次创建,多次重用”解决方案 - 无论使用哪种DBMS,我都会获得最佳性能。即使在那些足以重用查询计划的DBMS上,我仍然会避免重新执行C#代码和相关的垃圾收集压力。

答案 3 :(得分:0)

我认为这里的关键建议不是留下挥之不去的数据库连接,然后打开并临时运行。我注意到你的问题实际上是围绕是否重用一个命令 - 当看,注意到你的连接必须已经可以重用时...我不建议这样做,并建议你将每个数据库操作视为一个原子单元工作,包括连接利用率和所有。

答案 4 :(得分:0)

最好使用第一种方法,以便执行查询的逻辑保留在单个函数中。

答案 5 :(得分:0)

我认为正确的版本介于

之间
public foo() 
{
   var context = generateContext(dir);
   context.excute();
}

分开两个目标

  1. 创建上下文
  2. 执行
  3. 在创建上下文中,use可以使用singleton

答案 6 :(得分:0)

我更喜欢使用全局变量,而不是每次操作都重新创建相同的对象。 一次性分配成本很小,而每次迭代创建对象的成本都很高。