0

I've implimented the following code to search a list of objects for a particular value:

List<customer> matchingContacts = cAllServer
  .Where(o => o.customerNum.Contains(searchTerm) || 
              o.personInv.lastname.Contains(searchTerm) || 
              o.personDel.lastname.Contains(searchTerm))
  .ToList();

is there a quicker or cleaner way to impliment this search?

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
Dan Hall
  • 1,474
  • 2
  • 18
  • 43
  • 1
    Why? is this slower than you expect? – Rahul May 26 '17 at 12:38
  • This is the only way I'm aware of that will search all string fields specified in an object and return those list items, this is more of a question regarding if there is any potential optimisation or a cleaner way of implimenting. – Dan Hall May 26 '17 at 12:40
  • 1
    @DanHall no, there isn't – Samvel Petrosov May 26 '17 at 12:41
  • 1
    Yes there is. That's essentially Full Text Search. If `cAllServer` is a database server, you can use the server's FTS functionality. SQL Server for example offers FTS. If `cAllServer` is an in-memory list, you'd have to create a separate structure to speed up FTS searches. Just like BTrees, there are containers that accelerate such searches, although they are *not* trivial – Panagiotis Kanavos May 26 '17 at 12:41
  • @John I think you mean `for`, not `foreach`, though that's just a micro-optimization. – juharr May 26 '17 at 12:44

3 Answers3

1

Since you will have to iterate through all of the list items, it will have O(n) complexity. Performance also depends whether you are operating on IQueryable collection (with or without lazy loading) or it is a serialized IEnumerable collection. I'd advise to check first the properties that are most likely to have the value you are searching for, because you are using "or" operator, so that you can speed up your "Contains" operation. You iterate more quickly if you know that it is a match for a particular entity in 10ms rather than in 25ms. There is also a popular argument what is faster? Contains or IndexOf? Well IndexOf should be a little bit faster, but I doubt you'll notice it, unless you operate on lists with millions of elements. Is String.Contains() faster than String.IndexOf()?

papadoble151
  • 646
  • 8
  • 19
0

I think that this is fine as it is, but in other hand I'd think twice about the need to convert to list, you already are receving an IEnumerable type that'll let you iterate through stuff. Unless you need to go back and forth the list and searching by index there's no need for you to convert it to List.

This is an small optimization though.

Zalomon
  • 553
  • 4
  • 14
0

The one thing I'd suggest is to create a new "searchtext" column, prepopulated with (o.customerNum + "|" + o.personInv.lastname + "|" + o.personDel.lastname).ToUpper().

List<customer> matchingContacts = cAllServer
  .Where(o => o.searchtext.Contains(searchTerm))
  .ToList();

This performs one search instead of three (but on a longer string), and it you .ToUpper() searchTerm, you can perform a case-sensivitive search which migh tbe trivial faster.

On the whole, I wouldn't expect this to be significantly faster.

James Curran
  • 101,701
  • 37
  • 181
  • 258