2008-09-19 69 views
3

当从表中检索查找代码值,有些人做到这一点....NET中的“链接”语句是否有任何性能优势?

Dim dtLookupCode As New LookupCodeDataTable() 
Dim taLookupCode AS New LookupCodeTableAdapter() 
Dim strDescription As String 

dtLookupCode = taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL") 
strDescription = dtLookupCode.Item(0).Meaning 

...但是,我也看到了事情做好“链接”像这样...

strDescription = taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL").Item(0).Meaning 

...绕过具有自表适配器摆在首位的查找代码数据表知道它的结果集的结构样子。

是否使用“链接”方式保存创建数据表对象的开销呢,还是有效地获得,以妥善处理.Item(0).Meaning声明反正产生的?

+0

感谢Chris推荐“链接”的概念。我认为这更合适,并避免了“内联”的混淆。 – 2008-09-19 21:16:26

回答

4

从这个“内联”的一部分偏离,实际上,这两套代码不会编译出同样的事情。问题来了:

Dim dtLookupCode As New LookupCodeDataTable() 
Dim taLookupCode AS New LookupCodeTableAdapter() 

在VB中,这将创建新的对象与适当命名的引用。跟:

dtLookupCode = taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL") 

我们立即更换一个新对象时,它创建垃圾被收集原始dtLookupCode引用(在RAM不可达对象)。

因此,在确切的原始情况下,所谓的“内联”技术是,技术上,性能更高。 (但是,你不可能真的看到这个小的例子不同。)

其中代码将基本上是相同的是,如果原始样品如下地点:

Dim taLookupCode AS New LookupCodeTableAdapter 
Dim dtLookupCode As LookupCodeDataTable 
Dim strDescription As String 

dtLookupCode = taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL") 
strDescription = dtLookupCode.Item(0).Meaning 

在在这个世界上,我们只有现有的引用,而不是创建垃圾对象。为了便于阅读,我稍微重新排列了这些陈述,但其要点相同。此外,你可以很容易地像这样的单线初始化参考,并具有相同的基本思想是:

Dim taLookupCode AS New LookupCodeTableAdapter 
Dim dtLookupCode As LookupCodeDataTable = taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL") 
Dim strDescription As String = dtLookupCode.Item(0).Meaning 
2

呀,不说“内联”,因为这意味着特定的其他语言的东西。性能差异很可能是零或如此之小,这并不重要,这只是一个偏好问题。你想用单独的语句写出来使其更清楚,还是将它写在一行中以更快地输入?

5

这两条线可以编译成相同的东西。我会选择哪一个更容易阅读。内联通常是指a bit different

0

该结构仍然创建,您只是没有参考。

2

通常它只是使代码更不可读。

通常,当人们使用这种“内联”(即链接)时,他们将多次访问一个类的属性或字段,而不是只获取一次并存储在局部变量中。这通常是一个坏主意,因为人们通常不知道该字段或属性是如何返回的。例如,可以每次计算一次,或者可以计算一次并私下存储在课程中。

这里有两个插图。第一片段是可以避免对:

if (ConfigurationManager.AppSettings("ConnectionString") == null) 
{ 
    throw new MissingConfigSettingException("ConnectionString"); 
} 

string connectionString = ConfigurationManager.AppSettings("ConnectionString"); 

第二个是优选的:

string connectionString = ConfigurationManager.AppSettings("ConnectionString") 

if (connectionString == null) 
{ 
    throw new MissingConfigSettingException("ConnectionString"); 
} 

这里的问题是,AppSettings的()实际上具有拆箱所述的AppSettings集合每次一个值被检索:

// Disassembled AppSettings member of ConfigurationManager 

public static NameValueCollection AppSettings 
{ 
    get 
    { 
     object section = GetSection("appSettings"); 

     if ((section == null) || !(section is NameValueCollection)) 
     { 
      throw new 
       ConfigurationErrorsException(SR.GetString("Config_appsettings_declaration_invalid")); 
     } 

     return (NameValueCollection) section; 
    } 
} 
1

调试后者将是难上加难,如果您想通过阶段看到中间状态,和单步。

我会去可读性超过屏幕房地产,因为这里的性能使用量是一洗。

0

此:

dtLookupCode = taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL") 
strDescription = dtLookupCode.Item(0).Meaning 

这:

strDescription = taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL").Item(0).Meaning 

是完全等同的。

在第一个示例中,您已经获得了显式的临时引用(dtLookupTable)。在第二个示例中,临时引用是隐含的。在幕后,编译器几乎肯定会为这两者创建相同的代码。即使它没有发出相同的代码,额外的临时引用是非常便宜的。

不过,我不知道这行:

Dim dtLookupCode As New LookupCodeDataTable() 

是有效的。它看起来像这样创建了一个新的LookupCodeDataTable,然后当您在后面的语句中覆盖该变量时,它将被丢弃。我不VB程序,但我希望这条线应该是:

Dim dtLookupCode As LookupCodeDataTable 

参考便宜(可能免费),但构建一个额外的查找表可能不是。

+0

在VB中,你必须在使用表适配器之前声明新的数据表对象,否则你会得到空对象异常。有点奇怪,但这是它滚动的方式。 8^D – 2008-09-19 21:07:45

+0

尽管如此,您并未在您的示例中使用数据表对象。您立即覆盖参考。约翰鲁迪指出了同样的事情。 – 2008-09-19 22:13:35

1

我称之为链接。

你在问错误的问题。

你需要问的是:哪个更具可读性?

如果链接使得代码更易于阅读和理解,那么请继续操作。

但是,如果它混淆,那么不会。

任何性能优化都是不存在的。不要优化代码,优化算法。所以,如果你打算调用Item(1)和Item(2),那么通过链接,你会一遍又一遍地创建同一个对象,这是一个不好的算法。

在这种情况下,第一个选项会更好,因为您不需要每次都重新创建适配器。

1

反对“链接”的一个原因是Law of Demeter这表明您的代码在面对LookupCodeDataTable的更改时很脆弱。

您应该添加一个功能是这样的:

function getMeaning(lookupCode as LookupCodeDataTable) 
getMeaning=lookupCode.Item(0).Meaning 
end function 

,并调用它像这样:

strDescription=getMeaning(taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL")) 

现在getMeaning()可在其他许多地方,如果LookupCodeDataTable变化被调用,那么你只需要改变getMeaning()来修复它。

0

这是相同的,除非你需要 taLookupCode.GetDataByCodeAndValue指返回的对象(“EmpStatus”,“FULL”)或项目(0) 多次。否则,你不知道这个函数的运行时间是否是log(n)或n,所以为了最好的赌注,我会给它分配一个引用。

0

除了可维护性,还有一个避免链接的原因:错误检查。

是的,你可以把所有东西都包装在try/catch中,并且捕获链条任何部分都可以抛出的异常。

但是,如果您想验证不带try/catch的调用之间的结果,则必须将事情分开。例如:

  • GetDataByCodeAndValue返回null时会发生什么?
  • 如果它返回一个空列表呢?

如果您正在链接,则无法通过try/catch检查这些值。

相关问题