2

Is there a noticeable difference in performance/code quality if you use a string to compare at the start of an "if" instead of a boolean?

Example with string:

string isTrue = "true";
if (isTrue == "true"){
  // do something
}

Example with bool:

bool isTrue = true;
if (isTrue){
   //do something
}

I generally use a bool for these kind of comparisons but I've seen both variations online.

Lunatiic
  • 101
  • 2
  • 7
  • 12
    Do you really think it is a good idea to use #1? – Patrick Hofman Sep 27 '16 at 09:41
  • 7
    I can think of no sane reason to use a string to do a bool comparison... – Matthew Watson Sep 27 '16 at 09:41
  • I think a bool is faster. A boolean is 1 bit and a string is 8 bits. It is also much safer to use booleans then strings. – Luud van Keulen Sep 27 '16 at 09:42
  • 1
    Possible duplicate of [Parse to Boolean or check String Value](http://stackoverflow.com/questions/18329001/parse-to-boolean-or-check-string-value) – Teun van der Wijst Sep 27 '16 at 09:42
  • The only reason I can see for using the first is that you are forced to, for some reason. I can't think of a reason why you would be forced to, though (third party API that uses something other than "true" that isn't easily parsed to bool...?). – Ant P Sep 27 '16 at 09:42
  • 1
    @Luud "I think a bool is faster.". You think? I am pretty sure. – Patrick Hofman Sep 27 '16 at 09:42
  • A bool is exactly intended for a simple comparison if something is true or false. Thus there´s no reason to first convert this value to string and then compare the strings. Only reason I could imagine is that the string-value comes from a database or similar that serializes a boolean value to a string for whatever weird reason. Anyway you should compare based on bool. – MakePeaceGreatAgain Sep 27 '16 at 09:43
  • @PatrickHofman I say I think because I have no real evidence that it is faster ;) I'm sure there is evidence though. – Luud van Keulen Sep 27 '16 at 09:43
  • @PatrickHofman no way. I always use the second example. I'm just curious if it has any noteicable difference in performance overall. – Lunatiic Sep 27 '16 at 09:44
  • 4
    This is ridiculous. – ThePerplexedOne Sep 27 '16 at 09:45
  • Doesn't `==` compare references in C#. In which case the answer might not even be correct? – Bathsheba Sep 27 '16 at 09:45
  • @Bathsheba == works with string in C#. – Luud van Keulen Sep 27 '16 at 09:45
  • Define *noteicable*. Sure, if you´d execute this - say 1000000000 times, it *might* be slightly different. However I assume you have greater issues than this. – MakePeaceGreatAgain Sep 27 '16 at 09:45
  • So `==` does a character by character check? That's O(N). – Bathsheba Sep 27 '16 at 09:46
  • 2
    @Bathsheba It does a reference check first. Then a length check and then char by char. Code: http://referencesource.microsoft.com/#mscorlib/system/string.cs,31b307b02a3bd6b9 – Patrick Hofman Sep 27 '16 at 09:46

4 Answers4

5

Based on code generated on tryroslyn

Code:

using System;
public class C {
    public void M() {
        string isStringTrue = "true";
        if (isStringTrue == "true")
        {
            // do something
        }              

        bool isBoolTrue = true;
        if (isBoolTrue)
        {
            //do something
        }
    }
}

Produce IL code:

.class private auto ansi '<Module>'
{
} // end of class <Module>

.class public auto ansi beforefieldinit C
    extends [mscorlib]System.Object
{
    // Methods
    .method public hidebysig 
        instance void M () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 34 (0x22)
        .maxstack 2
        .locals init (
            [0] string,
            [1] bool,
            [2] bool,
            [3] bool
        )

        IL_0000: nop
        IL_0001: ldstr "true"
        IL_0006: stloc.0
        IL_0007: ldloc.0
        IL_0008: ldstr "true"
        IL_000d: call bool [mscorlib]System.String::op_Equality(string, string)
        IL_0012: stloc.2
        IL_0013: ldloc.2
        IL_0014: brfalse.s IL_0018
        IL_0016: nop
        IL_0017: nop
        IL_0018: ldc.i4.1
        IL_0019: stloc.1
        IL_001a: ldloc.1
        IL_001b: stloc.3
        IL_001c: ldloc.3
        IL_001d: brfalse.s IL_0021
        IL_001f: nop
        IL_0020: nop
        IL_0021: ret
    } // end of method C::M

    .method public hidebysig specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        // Method begins at RVA 0x207e
        // Code size 8 (0x8)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: nop
        IL_0007: ret
    } // end of method C::.ctor

} // end of class C

As you can see compare strings needs call method, compare bools don't need this.

BWA
  • 5,672
  • 7
  • 34
  • 45
3

Performance wise it is faster to compare two bools (Is the bit set or not?) vs. comparing two strings.

Code quality wise alternative #2 is to prefer. There isn't really any reason to use string comparison in this case when you have booleans available. It will obfuscate and make your code harder to understand and maintain.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
Henningsson
  • 1,275
  • 1
  • 16
  • 23
1

I decided to give it a try and created the following code:

Stopwatch watch = new Stopwatch();
string str1 = "MyTest";
string str2 = str1.Substring(0,2)+"Test";
watch.Start();
if(str1 == str2)
{
    Console.WriteLine("str1 == str2");
}
watch.Stop();
Console.WriteLine(watch.Elapsed);
watch.Restart();
var obj1 = (object)str1;
var obj2 = (object)str2;
if(obj1 == obj2)
{
    Console.WriteLine("obj1 == obj2");
}
watch.Stop();
Console.WriteLine(watch.Elapsed);
string str3 = "MyTest";
string str4 = "MyTest";
watch.Restart();
if (str3 == str4)
{
     Console.WriteLine("str3 == str4");
}
watch.Stop();
Console.WriteLine(watch.Elapsed);
watch.Restart();
watch.Restart();
var obj3 = (object)str3;
var obj4 = (object)str4;
if (obj3 == obj4)
{
    Console.WriteLine("obj3 == obj4");
}
watch.Stop();
Console.WriteLine(watch.Elapsed);
if (true)
{
     Console.WriteLine("true");
}
watch.Stop();
Console.WriteLine(watch.Elapsed);

it yielded the following result:

//str1 == str2  
//00:00:00.0564061 
//00:00:00.0000116 
//str3 == str4
//00:00:00.0103047 
//obj3 == obj4
//00:00:00.0000004 
//true 
//00:00:00.0000004

my two cents on the matter - by default, strings, if they are "hardcoded" are interned by the system, so str3 and str4 reference the same string. However, comparing two strings is always by value, so it actually has to run across the entire string. However, if the strings are interned (hold the same reference) and you convert them to an object it forces a by ref comperison - and that forces it to become a non costly operation, and actually have the same performence as checking a boolean.

** there should be an overhead of converting to object, but according to my tests, it seems unnoticable.

As for your question

obviously, checking a string is far more costly than checking a boolean, and is determined by the length of the strings, and how similar they are. So, using a string is not a good choice.

However

If you do use strings for checking equality - you should probably make sure they hold the same reference (str = str2 is an example) and check equality by ref.

(all of this is not really noticable, but still)

gilmishal
  • 1,884
  • 1
  • 22
  • 37
  • 1
    Thanks for taking your time and actually trying it out. It's interesting to see the second to last version being basically as fast as the boolean even though it's a lot clunkier and not as "clean" (in terms of readability) as the boolean. – Lunatiic Sep 27 '16 at 11:41
  • The question actually got me thinking about string comparison in general, and yes it is kinda odd - I guess if I tested more, it would show some difference, but it's probably exteremly minor. – gilmishal Sep 27 '16 at 11:45
  • I am gonna go ahead and guess that there is some optimization there, because the first ref comparison isn't as quick as the latter – gilmishal Sep 27 '16 at 11:47
0

In your case, the bool comparison will maintain better code quality then string comparison.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
Gorakh Nath
  • 9,140
  • 15
  • 46
  • 68
  • Any reference or proof? – Patrick Hofman Sep 27 '16 at 09:50
  • In bool, we explicitly passing the TRUE / FALSE. But in String comparison, first the compiler compare both values, then it returns TRUE/FALSE, Bool is a Single Step Processing, but any other datatype doing the same in two steps... – Gorakh Nath Sep 27 '16 at 10:16