Friday, June 30, 2006

Duck Typing for performance... lets face it when it comes to performace people attempt to squeeze every millisecond out of thier code. Duck Typing is a tremendious technique that Coldfusion's typeless nature affords us. It just so happens that Duck Typing can lead to tremendous performance improvements in CFC heavy applications. As many have commented while this is great it destroys the documentation in CFC explorer. Personally I think Duck Typing should be primarily used as a development technique not a performance booster. That being said it cannot be denied the performance you can get is pretty amazing. If you are using duck typing solely for performance gains its important to only use this in production. Your code that is used for auto documentation, in development, as well as stored in source control should have return types, types, and required attributes. You can accomplish this by appending the below ANT task to your deploy process, I would recommend deploying your Typeless CFCs to QA and production. Please note that anything you want stripped needs to have ducktype="true"* at the end of the tag:

<property name="path_to_project" location="../test/duck" />
<target name="Duck Type">
   <replaceregexp match="(cffunction[.\w]*?)([ ]?returntype)[ ]*?=[ ]*?(.)(.*?)\3[ ]?(?=(ducktype))"
      replace="\1 "
      flags="igm">
      <fileset dir="${path_to_project}"
   includes="**/*.cfc"/>
   </replaceregexp>

   <replaceregexp match="(cfargument.*?)([ ]?required)[ ]*?=[ ]*?(.)(.*?)\3[ ]?(?=(ducktype))"
   replace="\1 "
      flags="igm">
      <fileset dir="${path_to_project}"    includes="**/*.cfc"/>
   </replaceregexp>

      <replaceregexp match="(cfargument.*?)([ ]?type)[ ]*?=[ ]*?(.)(.*?)\3[ ]?(?=(ducktype))"
      replace="\1 "
      flags="igm">
   <fileset dir="${path_to_project}" includes="**/*.cfc"/>
   </replaceregexp>
</target>



If you prefer to not require the use of ducktype="true"
just remove (?=(ducktype)) from the match pattern. Additionally if you prefer to replace returntype="*" with returntype="any" instead of deleting it you can set replace equal to \1\2=\3any\3.

*It is worth noting that the regex simply matches ducktype as an attribute. You can have ducktype='false' or ducktype="goaway" and it will still convert your functions/arguments.