The strangest CF error ever: IP_ADD_MEMBERSHIP failed (out of hardware filters?)

So today I tried to cfdump something to see what was available for methods and data, but when I'd run the code with the cfdump in place, I would get:

view plain print about
1IP_ADD_MEMBERSHIP failed (out of hardware filters?)
2net.sf.ehcache.CacheException: IP_ADD_MEMBERSHIP failed (out of hardware filters?)
3at
4net.sf.ehcache.distribution.MulticastRMICacheManagerPeerProvider.init(MulticastRMICacheManagerPeerProvider.java:93)
5at net.sf.ehcache.CacheManager.init(CacheManager.java:241)
6at net.sf.ehcache.CacheManager.(CacheManager.java:221)

Remove the cfdump, things worked fine. Add it back in, get the error. I restarted the server, no good. So I googled. And I found something!! Google knows all, Google sees all.

Strangest freaking error message and behavior evar!

But, thanks to Microsoft via Brian Kotek through Ray Camden, I got the right idea... but the technote was for the wrong version of windows. Back to Google, Sauron's Eye of the Interwebs, and behold, an answer on Microsoft Answers.

Once you've issued the command-line bits you'll need to restart your J2EE server... but boom... it all worked!

And for those hearty souls that like the nitty-gritty, here's the dope on this issue.

UPDATE: OK, so it turns out I should have read the comments on Ray's blog entry, because the link status detect didn't fix the issue. Turns out it's a result of EHCache trying to use multicast (yes, that'd be UDP) over VPN... apparently notoriously unsupported but breaks CF's default EHCache settings. So, the solution is fairly simple, really...

Edit {jrun_home}/servers/{server_name}/cfusion.ear/cfusion.war/WEB-INF/cfusion/lib/ehcache.xml and remark out the following two lines:

view plain print about
1<cacheManagerPeerProviderFactory
2 class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
3 properties="peerDiscovery=automatic,
4 multicastGroupAddress=230.0.0.1,
5 multicastGroupPort=4446, timeToLive=1"

6 propertySeparator=","
7/>

8<cacheManagerPeerListenerFactory
9 class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"/>

Make those changes (the lines come after descriptive comments, I just moved the comment closer down 2 lines), restart your J2EE instance and you're golden!

Either that or spend your workday in isolation, dropped off VPN! lol

ColdFusion 9: cfscript DOES support rethrow!

In a conversation that came up during a meeting today, there was some discussion as to whether or not ColdFusion 9's beefed-up CF Script support included rethrow. Next thing you know a few of us dash off to test it.

Turns out it supports it as a statement. Also turns out that it's not mentioned in the ColdFusion 9 documentation, at least not in the sections that act as documentation for CF Script. Sadly, the whole CF Script section of the Developer's Guide kinda sucks and in the language reference (actually referred to as the CFML Language Reference) it's not mentioned outside the tag, and that just has a link to the Developer's Guide.

Blog time! So...

It works. And I also discovered a way of using it that I'd never thought of before. If you have a catch statement that does some things like logging or an alternate behavior or something, but then you want to return the flow to the built-in error handlers, you can do it like this:

view plain print about
1<cfscript>
2    try {
3        if (a==1) b=2;
4    } catch (any a) {
5        writeDump(var=a);
6        rethrow;
7    }
8
</cfscript>

I've only ever used it in CFCs where I was going to have deep composition and I wanted to be sure that a particular error was going to be the one that was seen. It changes where the error gets reported from, locally where the code is executing or from the caller's perspective. Without rethrow, the error will usually be reported from the caller's perspective instead local to the running code.

Happy throwing...

Laterz!

Output buffer, anyone??

Alright, now for the last and final debunking of the PHP vs ColdFusion - a test against time" post by our dear PHP apologist friend Mr. Phil Parsons. I'm sure by now he's deliriously happy he bothered to post that article in the first place. One thing you have to say for ColdFusion: the fans are fierce, loyal and knowledgeable. Challenge us only if you have your ducks in a row and your thinking cap on tight. And I'm sure if I try I can mix a few more metaphors before I finally sleep tonight.

Or we could just skip to the code...

So. I started out working with 200,000 characters. I mean, what fun is it if we can't outdo PHP at its own game, eh? I managed to roll 200,000 characters from local variable into a page buffer and into a different variable in .36ms. I have NO freaking clue why this particular test is significant, but apparently it's one of the ways in which PHP is purportedly better than ColdFusion. However, I just realized something:

Mr. Parsons is running a comparable CPU to mine, however he's running it overclocked at more than 1GHz faster than my lowly (and 4-year-old) MacBook Pro. Intel Core2 Duo 2.8 GHz LAPTOP vs AMD Phenom II X2 550 3.10 GHz @ 3.83 GHz DESKTOP. I wonder how my tests would run on a DESKTOP machine running a full GHz faster than my laptop? Especially considering that in general desktops GHz for GHz perform a bit better than laptops anyway?

So I dropped my character count to 140k, just like his and guess what? My poor, humble laptop burdened with running ColdFusion in a J2EE container, PHP5, Apache, Eclipse, FireFox, and about a half-dozen other things (I currently have 24MB of RAM free, yes, 24MB) managed to run his same test in .26ms. That's .06ms slower, on hardware running a full GHz slower. So you tell me which performs better.

Really... next time you decide to take on another platform with trickery and deceit, Mr. Parsons, think twice.

And now, finally, here's the code!

view plain print about
1<cfscript>
2    string = fileRead(expandPath('.') & "/resources/140kchars.txt");
3    its = 10000;
4    times = [];
5    writeOutput("Char count in the string: " & len(string) & "<br />");
6
</cfscript>
7
8<cfloop from="1" to="#its#" index="i">
9    <cfset start = getTickCount()>
10    <cfsavecontent variable="string2"><cfoutput>#string#</cfoutput></cfsavecontent>
11    <cfset end = getTickCount()>
12    <cfset arrayAppend(times,end-start)>
13</cfloop>
14<cfscript>
15    writeOutput("Char count in the new string: " & len(string2) & "<br />");
16    writeOutput("It took an average of " & arrayAvg(times) & " miliseconds to do whatever it was we just did " & its & " times.");
17
</cfscript>

Interestingly, the bigger the value in the its variable (the number of times we repeat the experiment) the FASTER OUR AVERAGE TIME IS. I just find that extremely interesting. God bless HotSpot. :)

Laterz!

OK, so let's talk object creation...

I'm making sort of a series out of poking holes in the anti-ColdFusion ramblings of an admittedly biased blogger. Pro-PHP blogger Phil Parsons blogged about how ColdFusion is tragically slower than PHP and is therefore something we should all stay away from if performance is any kind of concern. Unless we want to connect to MS Exchange... maybe.

So his second example was object instantiation performance. Arguably, one of ColdFusion's weak points... but not something entirely unworkable. People who complain about this generally only do so because they don't know how to best use CFC's and, most especially, how to write them properly. Nowhere is this more apparent than in Mr. Parsons' components. If this is how he writes CFCs it's no wonder his employer has "to constantly make decisions NOT to use OO features of Coldfusion based on [sic] it's poor performance." (That quote is from his comments below the article).

You can download the source he uses in the article, so I'm not going to post that here. I will say that the primary critiques I have against them are things like the ungodly amount of white space, the silly variable creation in the pseudo-constructor and the amazing number of unnecessary expressions.

What I am going to show you is my version, and then I'll share my results.

Colony.cfc

view plain print about
1<cfcomponent displayName="Colony" output="false">
2
3    <cffunction name="init" output="false" returntype="Colony">
4        <cfargument name="cn" type="String" default="colony">
5        <cfscript>
6            colonyName = arguments.cn;
7            drones = arrayNew(1);
8        
</cfscript>
9        <cfreturn this>
10    </cffunction>
11    
12    <cffunction name="addDrone" output="false" returntype="void">
13        <cfargument name="drone" type="Drone" required="true">
14        <cfset arrayAppend(drones, drone)>
15    </cffunction>
16    
17    <cffunction name="getDroneCount" output="false" returntype="numeric">
18        <cfreturn arrayLen(drones)>
19    </cffunction>
20
21</cfcomponent>

Drone.cfc:

view plain print about
1<cfcomponent displayname="Drone" output="false">
2    
3    <cffunction name="init" output="false" returntype="Drone">
4        <cfargument name="m" type="String" required="true" default="">
5        <cfset message = m>
6 <cfreturn this>
7 </cffunction>
8    
9    <cffunction name="getMessage" output="false" returntype="String">
10 <cfreturn message>
11 </cffunction>
12    
13    <cffunction name="setMessage" output="false" returntype="void">
14        <cfargument name="val" type="String" required="true">
15 <cfset message = val>
16 </cffunction>
17
18</cfcomponent>

colony.cfm:

view plain print about
1<cfscript>
2    Colony = new objects.Colony("colony1");
3    
4    start = getTickCount();
5    while (Colony.getDroneCount()
< 10000) {
6        Colony.addDrone(new objects.Drone());
7    }
8    end = getTickCount();
9    writeOutput("Adding 10,000 Drones to the Colony took " & end-start & " miliseconds.");
10</cfscript>

And now for the really bad news:

While I managed to blow his unquestionably inflated time of roughly 600ms or more right out of the water, ColdFusion continues to have a weak spot around object instantiation. The best I could do was slightly less than half of what Mr. Parsons got. I manged to get this test down to 250-300ms. Still substantially slower than the 42ms he reported for PHP. So while Mr. Parsons was grossly exaggerating the problem, the problem yet persists. Even with the drastic improvements the ColdFusion team managed to pack into ColdFusion 9.0.1 over previous versions.

The question you have to ask yourself, at that point, is whether it really makes any difference. CFCs (and OO in general, really) are about maintenance, and there are ways you should use them and ways you shouldn't. Not knowing those rules, or worse knowing them and deliberately refusing to use them, and then presenting yourself as someone with something worthwhile to say on the subject is just plain dishonest. It's been years since I've worked on an application that was written without CFCs, and even the ones that were poorly done performed adequately. The ones that were written with CFC best practices in mind were actually extremely performant.

In other words, there's no reason for anyone's employer to refuse to use them due to performance or any other reasons but ignorance, poor design and (worst of all) hyperbole. It's no different than knowing you should be using arrays instead of lists, or that structures are passed by reference and arrays by value. Go ahead, it's OK. Use CFCs in your applications... just do it intelligently, keeping in mind what works and (most important) what doesn't. And use ColdFusion's built-in data structures to their maximum advantage: structures, queries, arrays, oh my! Use the scopes, too: server (far too often overlooked), application, session, request, variables, this, super, caller, etc. The list goes on and on.

Programming is a craft. Craft your applications wisely and you'll never go wrong (unless you're looking to trash-talk something using bad science and worse code).

Laterz!

Dude, please try to be accurate.

People who skew the truth and deliberately mislead people make me angry. This post is a direct result of that phenomenon. If I sound irritated, well, it's only because I am. People who make a deliberate attempt to denigrate any platform based on artificial or manipulated results need to be called out on it. Letting a lie grow is, in my opinion, the same as telling it yourself...

In a recent post on his blog, Mr. Phil Parsons, self-professed CF "disliker" ("hater" seems a bit strong lol) and PHP aficionado, released several bits of code that claimed to demonstrate ColdFusion's performance inferiority to PHP. So I decided to see what was up with that myself. I wanted to see if it was true. I would have been happy to report that, yes, PHP is in fact faster than ColdFusion, here's my results. However the more I experimented and optimized both the PHP version and the ColdFusion version, the angrier I got about Mr. Parsons' blatant misrepresentation of the facts.

(NOTE: I didn't want to disprove him, I wanted to find out if it was true. If it's true, so what? This was a thought exercise, not an attempt to redeem ColdFusion (which really doesn't need redeeming anyway!))

Much thanks to Elliot Sprehn for helping me get a decently optimized prime number scanner that's practically bit-for-bit identical between PHP and ColdFusion. It's funny, because even his PHP code was pretty poorly written. According to the Mr. Parsons, the best PHP could do to calculate prime numbers up to 10,000 was 128ms. According to our optimized version of the scanner, PHP is capable of calculating prime numbers up to a value of 10,000 in 11.51ms.

Here's where the results get interesting:

ColdFusion, pathetic, ugly, poorly performant ColdFusion, despised and unpleasant to write with, actually did the same thing in 8.214ms.

Sorry Mr. Parsons... your "benchmarks" suck. ColdFusion is a full 3 and a quarter milliseconds faster!

I'm sure this will make or break a preponderance of web applications currently in development. /sarcasm

And incidentally, Mr. Parsons' professed goal with his post was specifically to prove ColdFusion inferior to PHP.

Ooops.

The test platform was:

  • Hardware: Apple MacBook Pro 2.8 GHz Core II Duo w/8GB RAM
  • Web server: Apache/2.2.15 (Unix) x64 (OS X Snow Leopard Default)
  • PHP: PHP 5.3.3 (cli) (OS X Snow Leopard Default)
  • CFML Engine: Adobe ColdFusion 9.0.1 x64 on JRun 4

And, for the record, none of the 3 server components were optimized in any way. Out-of-the-box and go.

Here's the code I used for each:

PHP:

view plain print about
1<?php
2
3function & primes($to) {
4 $primes = array(2, 3);
5 for ($i = 5; $i <= $to; ++$i) {
6 $root = sqrt($i);
7 for ($j = 0; $primes[$j] <= $root && $i % $primes[$j] != 0; ++$j);
8 if ($primes[$j] >
$root) {
9 array_push($primes, $i);
10 }
11 }
12 return $primes;
13}
14
15function arrayAverage($array) {
16    return array_sum($array)/count($array);
17}
18
19$times = array();
20
21for ($i = 0; $i < 1000; $i++ ) {
22    $t = microtime(true);
23    $primes = primes(10000);
24    array_push($times,microtime(true)-$t);
25}
26
27echo number_format(arrayAverage($times) * 1000, 5) . " miliseconds for " . count($times) . " iterations.";
28
29?>

Didja notice I had to roll my own average function? WTF?

ColdFusion:

view plain print about
1<cfscript>
2function primes(to) {
3 var primes = [2,3];
4 for (var i = 5; i
<= to; ++i) {
5 var root = sqr(i);
6 for (var j = 1; primes[j] <= root && i % primes[j] != 0; ++j);
7 if (primes[j] >
root) {
8 arrayAppend(primes, i);
9 }
10 }
11 return primes;
12}
13
14times = [];
15for (c=1;c<=1000;c++) {
16    start = getTickCount();
17    primes(10000);
18    arrayAppend(times,getTickCount()-start);
19}
20writeOutput( arrayAvg(times) & " miliseconds for " & arrayLen(times) & " iterations.");
21</cfscript>

BlogCFC was created by Raymond Camden. This blog is running version 5.9.7. Contact Blog Owner