title: Fastest way to compare objects in c#
body: <p>I am writing an application that validates some cities. Part of the validation is checking if the city is already in a list by matching the country code and cityname (or alt cityname).</p>
  
  <p>I am storing my existing cities list as:</p>
  
  <pre><code>public struct City
  {
      public int id;
      public string countrycode;
      public string name;
      public string altName;
      public int timezoneId;
  }
  
  List&lt;City&gt; cityCache = new List&lt;City&gt;();
  </code></pre>
  
  <p>I then have a list of location strings that contain country codes and city names etc. I split this string and then check if the city already exists.</p>
  
  <pre><code>string cityString = GetCity(); //get the city string
  string countryCode = GetCountry(); //get the country string
  city = new City();             //create a new city object
  if (!string.IsNullOrEmpty(cityString)) //don't bother checking if no city was specified
  {
      //check if city exists in the list in the same country 
      city = cityCache.FirstOrDefault(x =&gt; countryCode == x.countrycode &amp;&amp; (Like(x.name, cityString ) || Like(x.altName, cityString )));
      //if no city if found, search for a single match accross any country
      if (city.id == default(int) &amp;&amp; cityCache.Count(x =&gt; Like(x.name, cityString ) || Like(x.altName, cityString )) == 1)
          city = cityCache.FirstOrDefault(x =&gt; Like(x.name, cityString ) || Like(x.altName, cityString ));
  }
  
  if (city.id == default(int))
  {
      //city not matched
  }
  </code></pre>
  
  <p>This is very slow for lots of records, as I am also checking other objects like airports and countries in the same way. Is there any way I can speed this up? Is there a faster collection for this kind of comparison than List&lt;>, and is there a faster comparison function that FirsOrDefault()?</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>I forgot to post my Like() function:</p>
  
  <pre><code>bool Like(string s1, string s2)
      {
          if (string.IsNullOrEmpty(s1) || string.IsNullOrEmpty(s2))
              return s1 == s2;
          if (s1.ToLower().Trim() == s2.ToLower().Trim())
              return true;
  
          return Regex.IsMatch(Regex.Escape(s1.ToLower().Trim()), Regex.Escape(s2.ToLower().Trim()) + ".");
      }
  </code></pre>