.net “是否有任何绩效优势?”;“链接”;NET中的语句?

.net “是否有任何绩效优势?”;“链接”;NET中的语句?,.net,performance,.net,Performance,当从表中检索查找代码值时,有些人会这样做 Dim dtLookupCode As New LookupCodeDataTable() Dim taLookupCode AS New LookupCodeTableAdapter() Dim strDescription As String dtLookupCode = taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL") strDescription = dtLookupCode.Ite

当从表中检索查找代码值时,有些人会这样做

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
…它首先绕过了查找代码数据表,因为表适配器知道其结果集的结构


使用“chained”方法是否节省了创建数据表对象的开销,或者是否有效地创建了该对象以正确处理.Item(0).means语句?

是的,不要说“inline”,因为这在其他语言中意味着特定的内容。最有可能的是,性能差异要么为零,要么太小,这无关紧要,只是偏好的问题。你是想把它写在单独的语句中以使它更清楚,还是想把它全部写在一行中以更快地打印出来?

这两行将编译成相同的内容。我会选择哪个更容易让你读。内联通常指的是一些东西。

结构仍在创建中,您只是没有对它的引用。

通常它只会降低代码的可读性

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

这里有两个插图。要避免第一个片段:

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

如果您希望看到中间状态和阶段的单步执行,则调试后一个阶段将更加困难

因为性能是一种清洗,所以我会对这里使用的屏幕不动产的数量进行可读性分析。

实际上,这两组代码不会编译成相同的东西。这个问题伴随着:

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
这:

这是:

strDescription = taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL").Item(0).Meaning
它们是完全等价的

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

但是,我不确定这行:

Dim dtLookupCode As New LookupCodeDataTable()
效率很高。在我看来,这会创建一个新的
LookupCodeDataTable
,当您在后面的语句中覆盖变量时,它会被丢弃。我不使用VB编程,但我希望这一行应该是:

Dim dtLookupCode As LookupCodeDataTable
引用很便宜(可能是免费的),但构建额外的查找表可能不是这样。

我称之为链接

你问错问题了

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

如果链接使代码更容易阅读和理解,那么就去做吧

但是,如果它混淆了,那么不要

任何性能优化都是不存在的。不要优化代码,优化算法

因此,如果您要调用项(1)和项(2),那么通过链接,您将一次又一次地创建相同的对象,这是一个糟糕的算法


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

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

您应该添加如下函数:

function getMeaning( lookupCode as LookupCodeDataTable)
 getMeaning=lookupCode.Item(0).Meaning
end function
strDescription=getMeaning(taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL"))
这样称呼它:

function getMeaning( lookupCode as LookupCodeDataTable)
 getMeaning=lookupCode.Item(0).Meaning
end function
strDescription=getMeaning(taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL"))

现在可以在许多其他地方调用getMeansion(),如果LookupCodeDataTable发生更改,则只需更改getMeansion()即可修复它。

除非您需要通过 taLookupCode.GetDataByCodeAndValue(“EmpStatus”、“FULL”)或项(0)
多次。否则,您不知道此函数的运行时是log(n)还是n,因此最好的选择是给它分配一个引用

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

是的,您可以用try/catch来包装整个过程,并捕获链中任何部分可能抛出的每个异常

但是,如果您想在两次调用之间验证结果而不使用try/catch,那么您必须将它们分开。例如:

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

如果正在链接,则无法在没有try/catch的情况下检查这些值。

在VB中,必须先声明新的数据表对象,然后再对其使用表适配器,否则会出现null对象异常。有点奇怪,但就是这样。8^D不过,您在示例中没有使用数据表对象。您将立即覆盖引用。约翰·鲁迪也指出了同样的问题