ColdFusion结构直接赋值与对象文字表示法

ColdFusion结构直接赋值与对象文字表示法,coldfusion,Coldfusion,较新版本的ColdFusion(我相信CF 8和9)允许您使用类似于JSON的对象文字符号创建结构 我的问题是,对于本质上是静态的数据,使用对象文字符号比单独的赋值有什么特殊的好处(执行效率可能会更高) 例如: 对于个人作业,您可以这样做: var user = {}; user.Fname = "MyFirstnam"; user.Lname = "MyLastName"; user.titles = []; ArrayAppend(user.titles,'Mr'); ArrayAppend

较新版本的ColdFusion(我相信CF 8和9)允许您使用类似于JSON的对象文字符号创建结构

我的问题是,对于本质上是静态的数据,使用对象文字符号比单独的赋值有什么特殊的好处(执行效率可能会更高)

例如:

对于个人作业,您可以这样做:

var user = {};
user.Fname = "MyFirstnam";
user.Lname = "MyLastName";
user.titles = [];
ArrayAppend(user.titles,'Mr');
ArrayAppend(user.titles,'Dr.');
而对于对象文字,您可以执行以下操作

var user = {Fname = "MyFirstnam",
            Lname = "MyLastName",
            titles = ['Mr','Dr']};

这个有限的例子当然很简单,但是如果标题是一个结构数组(比如一个地址数组),那么文字符号就很难使用。

文字符号是声明性编程,而不是过程性编程

用文字符号,你可以一步清楚地告诉计算机你想要的是什么。如果没有文字符号,你会慢慢地、一块一块地、不清晰地构建你想要的东西

请注意,CF8中的文字符号充其量是笨拙和有缺陷的。它应该很少使用,然后只在简单的情况下使用。CF9中的文字表示法很好

对于CF8,您可以定义帮助程序:

function $A() {
    var r = [ ];
    var i = 0;
    var m = ArrayLen(Arguments);
    for(i = 1; i <= m; i += 1)
        ArrayAppend(r, Arguments[i]);
    return r;
}
function $S() {
    return StructCopy(Arguments);
}

这些助手一直在工作,保留结构键的大小写(结构键不只是大写,而是在键入时大写),并递归嵌套而不绑定。

在我尝试任何操作之前,我认为直接使用文本会更快,因为您可以在运行时创建所需的所有内容,并且不需要浪费时间创建变量,然后调用函数进行追加等等

然后我写了一个小测试,生成一个结果图表。你让我好奇:——)

结果证明我是对的,正如你所看到的,图表显示了惊人的差异:

但是请记住,尽管人们会使用文字符号,但我认为重要的是要记住,文字符号可能会很尴尬,而且在大多数情况下会让人更加困惑

显然,如果你正在开发一个真正需要速度提升的页面,那么文字符号就是你想要的,但是要注意,有时候在CF8上,它会产生一些奇怪的行为

仅向您展示我运行的测试类型:

<cfset aLiterals = arrayNew(1) />
<cfset aDirect = arrayNew(1) />

<cfsilent>
    <cfloop from="1" to="10000" index="mm">

        <!--- LITERAL --->
        <!--- start timer --->
        <cfset start = getTickcount() />
        <cfloop from="1" to="1000" index="ii">  
            <cfset user = {Fname = "MyFirstnam", Lname = "MyLastName", titles = ['Mr','Dr']} />
        </cfloop>
        <!--- end timer --->
        <cfset end = getTickCount()>

        <!--- Display total time --->
        <cfset total = end-start>
        <cfset arrayAppend(aLiterals,total) />

        <!--- DIRECT --->
        <!--- start timer --->
        <cfset start1 = getTickcount() />
        <cfloop from="1" to="1000" index="jj">
            <cfset user = {} />
            <cfset user.Fname = "MyFirstnam" />
            <cfset user.Lname = "MyLastName" />
            <cfset user.titles = [] />
            <cfset ArrayAppend(user.titles,'Mr') />
            <cfset ArrayAppend(user.titles,'Dr.') />
        </cfloop>

        <!--- end timer --->
        <cfset end1 = getTickCount()>

        <!--- Display total time --->
        <cfset total1 = end1-start1>
        <cfset arrayAppend(aDirect,total1) />   
    </cfloop>
</cfsilent>

<!--- The cfchart --->
<cfchart format="png" xaxistitle="function" yaxistitle="Loading Time (in secs.)">
    <cfchartseries type="bar" serieslabel="literal">
        <cfchartdata item="literal" value="#arrayAvg(aLiterals)#">
    </cfchartseries>
    <cfchartseries type="bar" serieslabel="direct">
        <cfchartdata item="direct" value="#arrayAvg(aDirect)#">
    </cfchartseries>
</cfchart>


希望这对您有所帮助。

谢谢。我理解其中的区别,我最感兴趣的是对象文字符号是否有一个特殊的优势,可以抵消静态数据的语法陷阱(嵌套括号/逗号),这两种方法都可以轻松完成。正如我在开始时提到的,文字符号是声明式编程,程序员简洁明了地表达他的意图。在过程编程中,程序员被简化为指定如何缓慢地、一步一步地构建数据结构,无法简洁、清晰地表达自己的意图。这篇文章的其余部分是关于文字符号及其在CF8和CF9中的使用的澄清。虽然人们可能不熟悉它,或者不经过实践就不习惯它,但是语法并不是一个陷阱——相反,语法让程序员得以自由。太棒了!正是我想要的。谢谢。感兴趣的注意:对于Railo 3.1.2,差异稍微小了一点,但仍然很重要。您并不是在对苹果进行比较。也许在第二个循环中,尝试使用关联数组表示法,然后再次运行性能测试。这对我来说有点令人震惊。原因是因为解析文字符号真的那么昂贵吗?我想不出direct比literal慢2.5倍的另一个原因。
<cfset aLiterals = arrayNew(1) />
<cfset aDirect = arrayNew(1) />

<cfsilent>
    <cfloop from="1" to="10000" index="mm">

        <!--- LITERAL --->
        <!--- start timer --->
        <cfset start = getTickcount() />
        <cfloop from="1" to="1000" index="ii">  
            <cfset user = {Fname = "MyFirstnam", Lname = "MyLastName", titles = ['Mr','Dr']} />
        </cfloop>
        <!--- end timer --->
        <cfset end = getTickCount()>

        <!--- Display total time --->
        <cfset total = end-start>
        <cfset arrayAppend(aLiterals,total) />

        <!--- DIRECT --->
        <!--- start timer --->
        <cfset start1 = getTickcount() />
        <cfloop from="1" to="1000" index="jj">
            <cfset user = {} />
            <cfset user.Fname = "MyFirstnam" />
            <cfset user.Lname = "MyLastName" />
            <cfset user.titles = [] />
            <cfset ArrayAppend(user.titles,'Mr') />
            <cfset ArrayAppend(user.titles,'Dr.') />
        </cfloop>

        <!--- end timer --->
        <cfset end1 = getTickCount()>

        <!--- Display total time --->
        <cfset total1 = end1-start1>
        <cfset arrayAppend(aDirect,total1) />   
    </cfloop>
</cfsilent>

<!--- The cfchart --->
<cfchart format="png" xaxistitle="function" yaxistitle="Loading Time (in secs.)">
    <cfchartseries type="bar" serieslabel="literal">
        <cfchartdata item="literal" value="#arrayAvg(aLiterals)#">
    </cfchartseries>
    <cfchartseries type="bar" serieslabel="direct">
        <cfchartdata item="direct" value="#arrayAvg(aDirect)#">
    </cfchartseries>
</cfchart>