what is faster: compare(str1,str), EQ, IS ?

141 views
Skip to first unread message

Mattijs Spierings

unread,
Dec 22, 2012, 8:10:52 AM12/22/12
to ra...@googlegroups.com
Hi,

From past experience using Marcomedia and/or Adobe Coldfusion I always used " Not compare(str1,str1) is 0" to test if strings are not equal.
Now I am wondering if this habit is outdated.
Is there any performance difference between :

Not Str1 eq Str2
Not Str is Str2
Not Compare(str1,str2) Is 0

Cheers,

Mattijs


Azadi Saryev

unread,
Dec 22, 2012, 11:20:16 AM12/22/12
to ra...@googlegroups.com
iirc, compare() is still the faster method (i remember reading something recently to that extent, but can't find it now).
but i wonder if the "IS 0" part in your expression - which is redundant - possibly makes it slower than the other methods?

Peter Boughton

unread,
Dec 22, 2012, 11:30:42 AM12/22/12
to ra...@googlegroups.com
In 99% of cases the answer is: it doesn't matter.

The only time it matters is when there is a measurable difference - otherwise, if you don't have any actual proof of speed differences, use the one that is most readable.


(If you really want to know, you can of course go look at the Railo source code for each method and see what precisely is done for each one.)

Bruce Kirkpatrick

unread,
Dec 22, 2012, 12:33:49 PM12/22/12
to ra...@googlegroups.com
Compare is the only way to do a case sensitive string comparison.   I use it for comparing strings in urls with the database so that content urls are always forced to be the most recent canonical url.

If you have a bigint column in mysql, compare() will preserve precision of the 64-bit value whereas EQ and IS will not be precise resulting in false positives due to rounding errors.  (You might need java biginteger for this to work as well)

I don't use compare for anything else just because it's less obvious what -1 and 1 means without referring to the documentation all the time.   0 is easy to understand.

Igal Sapir

unread,
Dec 22, 2012, 2:00:43 PM12/22/12
to Railo List

I think that what everyone here is trying to say is that yes, it is outdated.

I personally prefer the == and != operators, e.g.
str1 == str2
str1 != str2

Your code will not run on Old versions of ACF but...  Do you care? 

Also, as Bruce mentioned these are case insensitive comparisons so that's another factor to keep in mind.

Igal

--
typos, misspels, and other weird words brought to you courtesy of my mobile device.

Mattijs Spierings

unread,
Dec 22, 2012, 2:01:17 PM12/22/12
to ra...@googlegroups.com
All true.

Reason I am asking is that it the expression will be used in a script that might be triggered thousands of times a day (if my site become popuplar) or even more, so I just want the fastest possible option. Readability in this case is not an issue, I will use comment for that.

Azadi Saryev mentioned the IS 0 to be reduntant. Is it?
 I mean it can the following returns

  • -1, if string1 is less than string2

  • 0, if string1 is equal to string2

  • 1, if string1 is greater than string2

So when is it true?

Also, does it matter using EQ 0 or Is 0.
And is Not Compare() EQ 0 faster than Compare() NEQ 0 :) (i think NEQ is the same as <> which means it has to test if it is smaller and greater than so that would be less fast?)


Op zaterdag 22 december 2012 18:33:49 UTC+1 schreef Bruce Kirkpatrick het volgende:

Igal Sapir

unread,
Dec 22, 2012, 2:06:31 PM12/22/12
to Railo List

If is triggered thousands of times a day -- this really isn't an issue.

If its triggered thousands of times a minute -- you should look into it by testing and collecting empirical data.

Igal

--
typos, misspels, and other weird words brought to you courtesy of my mobile device.

AJ Mercer

unread,
Dec 22, 2012, 6:41:10 PM12/22/12
to ra...@googlegroups.com
Looks like a candidate for Mark Drew's CFML Myth Busters ;-)

May also add a test for a function that returns a Boolean with EQ 0


--

AJ Mercer
<webonix:net strength="Industrial" /> | <webonix:org community="Open" />
http://twitter.com/webonix

Peter Boughton

unread,
Dec 22, 2012, 6:43:07 PM12/22/12
to ra...@googlegroups.com
Mattijs wrote:
> Reason I am asking is that it the expression will be used in a script that
> might be triggered thousands of times a day (if my site become popuplar)


Firstly, as Igal says, thousands of times a day is nothing for a modern system. All of the options will cope fine with that - you'll have plenty of other bottlenecks to worry about first.

Secondly, you've confirmed that this is premature optimisation. Whilst fast code is generally preferred, your focus should be on creating working maintainable code, (and not being distracted by issues such as this).

Once you have a completed application with a full set of tests and nothing better to do, then you can profile it to determine if this have any meaningful difference, and then make informed changes as required.



> Azadi Saryev mentioned the IS 0 to be reduntant. Is it?

Yes, if you remove the NOT at the start too.

0 is false, -1 and 1 are both true.

(It is perfectly valid to rely on the automatic conversion of integers to boolean.)



> Also, does it matter using EQ 0 or Is 0.

They are both aliases for the same operator, and thus produce the same bytecode.

Again, Railo is Open Source; you can look at the source and see this...

https://github.com/getrailo/railo/blob/master/railo-java/railo-core/src/railo/transformer/cfml/expression/AbstrCFMLExprTransformer.java#L503
https://github.com/getrailo/railo/blob/master/railo-java/railo-core/src/railo/transformer/cfml/expression/AbstrCFMLExprTransformer.java#L582

...both operators result in the same call:

    expr = decisionOpCreate(data,OPDecision.EQ,expr);


(FWIW, it looks like this operator then results in the same string comparison method as compareNoCase, but I'm not going to spend time looking in detail for the reasons given below.)



> Not Compare() EQ 0 faster than Compare() NEQ 0 :) (i think NEQ is
> the same as <> which means it has to test if it is smaller and greater than
> so that would be less fast?)


Again, this question is almost certainly just wasted brain power. Any difference between them is almost certainly completely insignificant and overshadowed by other areas of your code.

Use NOT compare(a,b) if you're looking for equal strings and compare(a,b) if you're looking for unequal strings.
If case isn't important, use EQ, NEQ, compareNoCase, or NOT compareNoCase, as preferred.


Any supposed performance issue doesn't exist until you've measured/profiled your application appropriately.

If you have done appropriate speed/load tests then you have something to compare against and can do practical tests to get actual results, (and if you do discover anything interesting there it'd be great to know).

Without such testing you're just worrying over premature optimisation and it is better use of your time to trust in Micha squeezing the best performance out of Railo, so that you can concentrate on what your application is doing. :)

Ronan Lucio

unread,
Dec 26, 2012, 12:55:53 PM12/26/12
to ra...@googlegroups.com
Mattijs,

I guess it's outdated.
Compare() tends to be a bit faster and, of course, it's still an option.
In the other hands, I guess there isn't a relevant gain using it.

I did the same question a few years ago.
Unfortunately I didn't find the thread, but I remember Michael did a test with some options getting execution time for each one.
The result wasn't so different.
So I can suggest you to do the same: Just create a big loop and execute it with each option. Take the time to execute each one and post the result for us... ;-)
 


2012/12/22 Mattijs Spierings <mattijss...@gmail.com>

Igal @ getRailo.org

unread,
Dec 26, 2012, 3:05:44 PM12/26/12
to ra...@googlegroups.com
I didn't test this, but I really don't think that [Compare( a, b ) EQ 0] would be faster than [Equals( a, b )], which is the operator used for EQ, IS, ==, etc;  at the very least, when you do Compare() you generate an integer that is than compared again with 0, so you have another unneeded test.

the Equals operator is (or at least should be) optimized for its use, so for example if the length of two strings is not equal, Equals() return false -- before doing any character comparison.

the bottom line is that:

    1) I don't think that you gain anything from this
    2) even if you do gain anything it would be so minute that it isn't worth cluttering the code

ACTUALLY:  after looking at the code -- it looks like there is room for improvement there.  I will discuss it with Micha because there's a good chance that he already considered it and decided against it.
https://github.com/getrailo/railo/blob/develop/railo-java/railo-core/src/railo/runtime/op/Operator.java#L492

the Operator class (and Equals() in particular) is a very hot spot so it's worth looking into.

my "bottom line" points above still apply though, and now -- here's the problem with premature/over optimization:  if you optimize your code to work faster with the old implementation, then when we optimize the implementation in the new method, you code will actually perform worse than it would have had you just wrote your code without worrying over that stuff.


Igal

Chris Blackwell

unread,
Dec 27, 2012, 2:48:35 PM12/27/12
to ra...@googlegroups.com
I quite often just use the equals() method exposed by the underlying java class
this is a case and type sensitive comparison, ie.

"1".equals(1) --> false
"one".equals("One") --> false

Chris

Igal Sapir

unread,
Dec 27, 2012, 2:51:17 PM12/27/12
to Railo List

This method is actually slower because it resorts to reflection.

You should try to always use the BIFs out the new Railo member functions.

Igal

--
typos, misspels, and other weird words brought to you courtesy of my mobile device.

Adam Cameron

unread,
Dec 28, 2012, 7:50:16 AM12/28/12
to ra...@googlegroups.com
I've been keenly reading this thread over the Xmas break.

I'd just like to add that Peter's comment in bold below is the most important thing said so far.

All this discussion about what's going to be the better performer is just symptoms of premature optimisation. You only need to concern yourself with this sort of performance consideration if you find yourself having a problem, and - to be frank - the difference between ways of doing a string comparison are going to have such shrinkingly trivial performance differences I doubt it would ever be a serious place to look for improvements in almost all situations. More relevant performance considerations will be found in almost any other place in your code. Look at things like writing better SQL (or reducing DB hits), make fewer function calls / CFC instantiations, move processing to the DB / from the DB etc are all going to contribute in a statistically meaningful way more than the type of string comparison (or boolean comparison) one does. So don't worry about it.

On the other hand, writing clear code is going to be far more important in these situations than shaving a millisecond per ten thousand iterations (or such like). Personally I'd use compare() if a case-sensitive, or precision-lossless comparison is needed, otherwise use == (or some facsimile thereof).

--
Adam

kencl

unread,
Dec 28, 2012, 9:30:03 PM12/28/12
to ra...@googlegroups.com
 to be frank - the difference between ways of doing a string comparison are going to have such shrinkingly trivial performance differences I doubt it would ever be a serious place to look for improvements
On Saturday, 22 December 2012 16:30:42 UTC, Peter Boughton wrote:
In 99% of cases the answer is: it doesn't matter.


There are use cases where it matters.  You have no way of knowing what problem a coder is solving.  Leave it to the programmer to be smart enough to know whether this is an optimization or a waste of time.  If knowledge is power then more knowledge is more power.  You never know who benefits from a deeper understanding of comparison internals, so don't try to cut short the conversation just because it isn't useful to you.

Adam Cameron

unread,
Dec 29, 2012, 5:14:19 AM12/29/12
to ra...@googlegroups.com
Right, and in this case, the most useful knowledge to take away from the topic is "don't worry about premature optimisation".  As a reminder, the OP was asking in regard to code that's only being called in the order of 1000s of times per day (so: not enough to worth worrying about, unless perhaps it's all concurrent within the space of a few seconds. I'm sure they would have mentioned that though ;-). So the chief take-away from this is "this would be a case of premature optimisation, so don't worry". Peter's statement to that effect was by far the most useful thing so far said on this thread. I was just re-iterating this by way of support.

As for an indepth analysis of which string comparison method is actually the most performant if it actually matters (and, yes, as you say there are theoretically those edge cases wherein it could make a difference), this is nothing of substance in this thread, because all anyone is doing is speculating. No-ones offered up an experiment or results or any sort of demonstration of anything. There's no problem with this, but this is *not* a thread about the lower-level workings of what's going on, and not in any way useful as far as a discussion on that sort of thing goes.  Again, nor does it need to be, but it demonstrates that the best knowledge here - in answer to the OP's question - is "don't worry about it".

Being realistic about things, in a web environment (and one being served by a CFML server), the bulk of the time taken for a request is going to be comms between client and server sides across the network, then it's going to be any calls the CFML server makes to external systems like DBs etc. After that it'll be the size of the returned document (does it have egregious whitespace that isn't being dealt with? Is the mark-up poor, and not taking full advantage of CSS?). Then all the various things that a Yslow sort of analysis might offer up as being tuneable. At some stage, one needs to look at the CFML code too... is the person using lists where they could be using arrays? Are they using <cfinvoke> to continually recreate transient objects rather than reusing a singleton? Are they using a framework where a more "flat" approach might be better for a page that must perform (frameworks are lovely, but they always add overhead). Do they have the trusted cache switched on? Are their JVM settings well-tuned? Have they got CFC type checking switched off? Have they got compiled classes saved to the file system (I dunno about on Railo, but on CF this can degrade performance in some situations). Should they perhaps fob some processing off to a separate thread, or queue it in some way, or something like that?  Thinking about strings specifically... if we need to eke performance out there, are they using StringBuffers rather than strings for mutable string operations? Are they performing string operations in the most performant order, eg: building a big string then checking its validity instead of perhaps re-thinking some of the logic to do the cheaper stuff first.

The thing is, if you're in the real world, and you have a performance problem on a page... there will be places to win and win in a more meaningful way that to piss around wondering about string comparison operators (or, worse, whether or not to put "EQ TRUE" in a boolean expression). Any of the factors above could shave time off a request in the orders of 100s or at least tens or even single milliseconds. Unless there are an egregious amount of string operations going on - on very large strings - "which string compare operation you are using" is simply almost always not going to be a consideration. In the real world.

However in the theoretical world, yup: worth considering - if only to know the answer. Has this thread progressed that knowledge acquisition at all? Not thusfar. Now I don't see any problem with that at all... it's just a Xmas time chat.  But, kencl, you could take your own advice and not try cutting someone short (which, after all, is what you are suggesting I do, isn't it) when they're actually adding something meaningful to the conversation. Unlike, I might add, yourself.

Cheers.

--
Adam

Adam Cameron

unread,
Dec 31, 2012, 11:40:48 AM12/31/12
to ra...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages