// Collection of code snippets by Arne Vajhøj // posted to eksperten.dk, usenet and other places (2002-now) using System; using System.Linq; using System.Globalization; using System.Threading; namespace Dec2 { public class Program { private static int TestToLower(string[] source, string searchTerm) { var matchQuery = from word in source where word.ToLowerInvariant() == searchTerm.ToLowerInvariant() select word; return matchQuery.Count(); } private static int TestToLowerX(string[] source, string searchTerm) { var matchQuery = from word in source where word.ToLower() == searchTerm.ToLower() select word; return matchQuery.Count(); } private static int TestStringComparison(string[] source, string searchTerm) { var matchQuery = from word in source where string.Equals(word, searchTerm, StringComparison.InvariantCultureIgnoreCase) select word; return matchQuery.Count(); } private static int TestStringComparisonX(string[] source, string searchTerm) { var matchQuery = from word in source where string.Equals(word, searchTerm, StringComparison.CurrentCultureIgnoreCase) select word; return matchQuery.Count(); } private const int N = 10000; public static void Main(string[] args) { string text = @"Historically, the world of data and the world of objects" + @" have not been well integrated. Programmers work in C# or Visual Basic" + @" and also in SQL or XQuery. On the one side are concepts such as classes," + @" objects, fields, inheritance, and .NET Framework APIs. On the other side" + @" are tables, columns, rows, nodes, and separate languages for dealing with" + @" them. Data types often require translation between the two worlds; there are" + @" different standard functions. Because the object world has no notion of query, a" + @" query can only be represented as a string without compile-time type checking or" + @" IntelliSense support in the IDE. Transferring data from SQL tables or XML trees to" + @" objects in memory is often tedious and error-prone."; string searchTerm = "data"; string[] source = text.Split(new char[] { '.', '?', '!', ' ', ';', ':', ',' }, StringSplitOptions.RemoveEmptyEntries); CultureInfo[] cis = { Thread.CurrentThread.CurrentCulture, new CultureInfo("da-DK", false), new CultureInfo("en-US", false), CultureInfo.InvariantCulture }; foreach(CultureInfo ci in cis) { Thread.CurrentThread.CurrentCulture = ci; Console.WriteLine("Culture = " + ci.DisplayName); Console.WriteLine("original: " + TestToLower(source, searchTerm)); Console.WriteLine("modified: " + TestToLower(source, searchTerm)); Console.WriteLine("suggested: " + TestStringComparison(source, searchTerm)); Console.WriteLine("modified: " + TestStringComparisonX(source, searchTerm)); Console.WriteLine("original: " + TestToLower(new string[] { "Ålborg" }, "aalborg")); Console.WriteLine("modified: " + TestToLower(new string[] { "Ålborg" }, "aalborg")); Console.WriteLine("suggested: " + TestStringComparison(new string[] { "Ålborg" }, "aalborg")); Console.WriteLine("modified: " + TestStringComparisonX(new string[] { "Ålborg" }, "aalborg")); DateTime dt1 = DateTime.Now; for(int i = 0; i < N; i++) { TestToLower(source, searchTerm); } DateTime dt2 = DateTime.Now; Console.WriteLine("original: " + (dt2-dt1).TotalSeconds); DateTime dt3 = DateTime.Now; for(int i = 0; i < N; i++) { TestToLowerX(source, searchTerm); } DateTime dt4 = DateTime.Now; Console.WriteLine("modified: " + (dt4-dt3).TotalSeconds); DateTime dt5 = DateTime.Now; for(int i = 0; i < N; i++) { TestStringComparison(source, searchTerm); } DateTime dt6 = DateTime.Now; Console.WriteLine("suggested: " + (dt6-dt5).TotalSeconds); DateTime dt7 = DateTime.Now; for(int i = 0; i < N; i++) { TestStringComparisonX(source, searchTerm); } DateTime dt8 = DateTime.Now; Console.WriteLine("modified: " + (dt8-dt7).TotalSeconds); } } } }