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.

2 comments:

cybersonic said...

Thanks for posting this! I shall see if I can integrate some action like this into CFEclipse at some point! A definate winner

Jim said...

I just stumbled on your post here (catching up on my reading!)

I'm trying to get your ANT task working but have a regex question:

This doesn't seem to work:
(cffunction[.\w]*?)

But if I change it like the cfargument check:
(cfargument.*?)

It seems to work. I've got a build that pulls down my code from SVN and then runs this and copies it to another directory - I can then do a diff on it to see what changed.

Any reason not to just use .*?

Thanks! Great post!
Jim