Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
SolvedPrivate

Is this an "expensive" operation?

Posted on 2015-01-06
6
Medium Priority
?
47 Views
Last Modified: 2016-02-17
I got help from an EE member and I used it. Someone here says it's "an expensive" operation. Is it?

 public bool ValidateSubmission(ConsumerModel model)
        {
            
            //1. check if productId, PromotionId and Serial number exist 
            var p = (....
                select s);

            if (p.Any()) //row exists
                throw new ArgumentException("some message here");

      //3 more checks like this here

Open in new window


I call it like this

 try
                    {
                        _repository.ValidateSubmission(model); 
                    }

Open in new window

0
Comment
Question by:Camillia
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
6 Comments
 
LVL 34

Expert Comment

by:it_saige
ID: 40534141
If you are checking against p 4 times, then yes, it is an expensive operation.  Consider the following (for illustrative purposes):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace EE_Q28591670
{
	class Program
	{
		static List<SomeObject> data = new List<SomeObject>();

		static void Main(string[] args)
		{
			SomeObject result = null;
			var watch = new Stopwatch();
			for (int i = 0; i < 1000000; i++)
				data.Add(new SomeObject() { ID = i, Name = string.Format("SomeName{0}", i), Created = DateTime.Now.AddDays(i), IsActive = (i % 2) == 0 });

			watch.Start();
			ValidateSubmission(99999);
			watch.Stop();
			Console.WriteLine();
			Console.WriteLine("ValidateSubmission took {0}ms.", watch.ElapsedMilliseconds);
			Console.WriteLine();
			watch.Reset();
			watch.Start();
			result = GetSpecificRecord(99999);
			watch.Stop();
			Console.WriteLine("GetSpecificRecord took {0}ms.", watch.ElapsedMilliseconds);
			Console.ReadLine();
		}

		private static void ValidateSubmission(int id)
		{
			var p = (from item in data select item);

			if (p.Any(x => x.ID.Equals(id)))
				Console.WriteLine("Found ID in set = {0}", p.Where(x => x.ID.Equals(id)).FirstOrDefault().ID);

			if (p.Any(x => x.Name.Contains(id.ToString())))
				Console.WriteLine("Found Name in set = {0}", p.Where(x => x.Name.Contains(id.ToString())).FirstOrDefault().Name);

			if (p.Any(x => x.Created.Date.Equals(DateTime.Now.AddDays(id).Date)))
				Console.WriteLine("Found Date in set = {0:MM/dd/yyyy}", p.Where(x => x.Created.Date.Equals(DateTime.Now.AddDays(id).Date)).FirstOrDefault().Created);
		}

		private static SomeObject GetSpecificRecord(int id)
		{
			return (from item in data where item.ID.Equals(id) select item).SingleOrDefault();
		}
	}

	class SomeObject
	{
		public int ID { get; set; }
		public string Name { get; set; }
		public DateTime Created { get; set; }
		public bool IsActive { get; set; }
	}
}

Open in new window

Which produces the following output -Capture.JPG-saige-
0
 
LVL 7

Author Comment

by:Camillia
ID: 40534155
It's checking against 4 LINQ statements (I should've been clear). Below. Would that make a difference?

 var p = (.....
                select s);

            if (p.Any()) //row exists
                throw new ArgumentException("msg here");

                  
            
            var x = (......
                select s);

            if (!x.Any())
                throw new ArgumentException("msg here");

               var y = (......
                select s);
            if (!y.Any())
                throw new ArgumentException("msg here");

            //4. if product selected is not in promotion
            var y1 = (....
                select s);

            if (!y1.Any())
                throw new ArgumentException("some msg here");

            return true;

Open in new window

0
 
LVL 34

Expert Comment

by:it_saige
ID: 40534178
The more linq statements you check against, the more costly your operation becomes.  This is because specifying:
var y1 = (from foo in bar where someCriteria() select foo)

Open in new window

Does not actually do anything except setup an Enumerator.  It's only when you do something:
if (!y1.Any())

Open in new window

That you access the enumeration to validate the condition.  And it should be implied that whenever you access the enumeration, you are performing a loop operation.

If you look at my example, I only used one linq statement but I looped through the enumeration 6 times.  For comparison consider the following:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace EE_Q28591670
{
	class Program
	{
		static List<SomeObject> data = new List<SomeObject>();

		static void Main(string[] args)
		{
			SomeObject result = null;
			var watch = new Stopwatch();
			for (int i = 0; i < 1000000; i++)
				data.Add(new SomeObject() { ID = i, Name = string.Format("SomeName{0}", i), Created = DateTime.Now.AddDays(i), IsActive = (i % 2) == 0 });

			watch.Start();
			ValidateSubmission(99999);
			watch.Stop();
			Console.WriteLine();
			Console.WriteLine("ValidateSubmission took {0}ms.", watch.ElapsedMilliseconds);
			Console.WriteLine();
			watch.Reset();
			watch.Start();
			result = GetSpecificRecord(99999);
			watch.Stop();
			Console.WriteLine("GetSpecificRecord took {0}ms.", watch.ElapsedMilliseconds);
			Console.WriteLine();
			watch.Reset();
			watch.Start();
			EfficientValidateSubmission(99999);
			watch.Stop();
			Console.WriteLine();
			Console.WriteLine("EfficientValidateSubmission took {0}ms.", watch.ElapsedMilliseconds);
			Console.ReadLine();
		}

		private static void ValidateSubmission(int id)
		{
			var p = (from item in data select item);

			if (p.Any(x => x.ID.Equals(id)))
				Console.WriteLine("Found ID in set = {0}", p.Where(x => x.ID.Equals(id)).FirstOrDefault().ID);

			if (p.Any(x => x.Name.Contains(id.ToString())))
				Console.WriteLine("Found Name in set = {0}", p.Where(x => x.Name.Contains(id.ToString())).FirstOrDefault().Name);

			if (p.Any(x => x.Created.Date.Equals(DateTime.Now.AddDays(id).Date)))
				Console.WriteLine("Found Date in set = {0:MM/dd/yyyy}", p.Where(x => x.Created.Date.Equals(DateTime.Now.AddDays(id).Date)).FirstOrDefault().Created);
		}

		private static void EfficientValidateSubmission(int id)
		{
			var p = (from item in data where item.ID.Equals(id) && item.Name.Contains(id.ToString()) && item.Created.Date.Equals(DateTime.Now.AddDays(id).Date) select item).FirstOrDefault();

			if (p != null)
			{
				Console.WriteLine("Found ID in set = {0}", p.ID);
				Console.WriteLine("Found Name in set = {0}", p.Name);
				Console.WriteLine("Found Date in set = {0:MM/dd/yyyy}", p.Created);
			}
		}

		private static SomeObject GetSpecificRecord(int id)
		{
			return (from item in data where item.ID.Equals(id) select item).SingleOrDefault();
		}
	}

	class SomeObject
	{
		public int ID { get; set; }
		public string Name { get; set; }
		public DateTime Created { get; set; }
		public bool IsActive { get; set; }
	}
}

Open in new window

Which produces the following results -Capture.JPG-saige-

P.S. - And in case you are wondering why there is a discrepency in EfficientValidationSubmission vs GetSpecifiedRecord.  It is because GetSpecifiedRecord uses SingleOrDefault (which has to look at every object in the enumeration to ensure that there is only one object that matches the search criteria); whereas EfficientValidationSubmission uses FirstOrDefault() (which returns the first object).
0
CHALLENGE LAB: Troubleshooting Connectivity Issues

Goal: Fix the connectivity issue in the lab's AWS environment so that you can SSH into the provided EC2 instance.  

 
LVL 7

Author Comment

by:Camillia
ID: 40534188
This guy says the issue for being it expensive is that I used throw instead of just returning a string back. True?
0
 
LVL 34

Accepted Solution

by:
it_saige earned 2000 total points
ID: 40534217
It is true that throwing exceptions can be more costly than result based returns.

Exceptions and Performance

And for proof of concept, consider the following:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace EE_Q28591670
{
	class Program
	{
		static List<SomeObject> data = new List<SomeObject>();

		static void Main(string[] args)
		{
			SomeObject result = null;
			var watch = new Stopwatch();
			for (int i = 0; i < 1000000; i++)
				data.Add(new SomeObject() { ID = i, Name = string.Format("SomeName{0}", i), Created = DateTime.Now.AddDays(i), IsActive = (i % 2) == 0 });

			watch.Start();
			ValidateSubmission(99999);
			watch.Stop();
			Console.WriteLine();
			Console.WriteLine("ValidateSubmission took {0}ms.", watch.ElapsedMilliseconds);
			Console.WriteLine();
			watch.Reset();
			watch.Start();
			result = GetSpecificRecord(99999);
			watch.Stop();
			Console.WriteLine("GetSpecificRecord took {0}ms.", watch.ElapsedMilliseconds);
			Console.WriteLine();
			watch.Reset();
			watch.Start();
			EfficientValidateSubmission(99999);
			watch.Stop();
			Console.WriteLine();
			Console.WriteLine("EfficientValidateSubmission took {0}ms.", watch.ElapsedMilliseconds);
			Console.WriteLine();
			watch.Reset();
			watch.Start();
			try
			{
				ExceptionValidateSubmission(99999);
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message);
			}
			watch.Stop();
			Console.WriteLine();
			Console.WriteLine("ExceptionValidateSubmission took {0}ms.", watch.ElapsedMilliseconds);
			Console.WriteLine();
			watch.Reset();
			watch.Start();
			Console.WriteLine(ResultValidateSubmission(99999));
			watch.Stop();
			Console.WriteLine();
			Console.WriteLine("ResultValidateSubmission took {0}ms.", watch.ElapsedMilliseconds);
			Console.ReadLine();
		}

		private static void ValidateSubmission(int id)
		{
			var p = (from item in data select item);

			if (p.Any(x => x.ID.Equals(id)))
				Console.WriteLine("Found ID in set = {0}", p.Where(x => x.ID.Equals(id)).FirstOrDefault().ID);

			if (p.Any(x => x.Name.Contains(id.ToString())))
				Console.WriteLine("Found Name in set = {0}", p.Where(x => x.Name.Contains(id.ToString())).FirstOrDefault().Name);

			if (p.Any(x => x.Created.Date.Equals(DateTime.Now.AddDays(id).Date)))
				Console.WriteLine("Found Date in set = {0:MM/dd/yyyy}", p.Where(x => x.Created.Date.Equals(DateTime.Now.AddDays(id).Date)).FirstOrDefault().Created);
		}

		private static void ExceptionValidateSubmission(int id)
		{
			var p = (from item in data select item);

			if (p.Any(x => x.ID.Equals(id)))
				throw new Exception(string.Format("Found ID in set = {0}", p.Where(x => x.ID.Equals(id)).FirstOrDefault().ID));

			if (p.Any(x => x.Name.Contains(id.ToString())))
				throw new Exception(string.Format("Found Name in set = {0}", p.Where(x => x.Name.Contains(id.ToString())).FirstOrDefault().Name));

			if (p.Any(x => x.Created.Date.Equals(DateTime.Now.AddDays(id).Date)))
				throw new Exception(string.Format("Found Date in set = {0:MM/dd/yyyy}", p.Where(x => x.Created.Date.Equals(DateTime.Now.AddDays(id).Date)).FirstOrDefault().Created));
		}

		private static string ResultValidateSubmission(int id)
		{
			var p = (from item in data select item);

			if (p.Any(x => x.ID.Equals(id)))
				return string.Format("Found ID in set = {0}", p.Where(x => x.ID.Equals(id)).FirstOrDefault().ID);

			if (p.Any(x => x.Name.Contains(id.ToString())))
				return string.Format("Found Name in set = {0}", p.Where(x => x.Name.Contains(id.ToString())).FirstOrDefault().Name);

			if (p.Any(x => x.Created.Date.Equals(DateTime.Now.AddDays(id).Date)))
				return string.Format("Found Date in set = {0:MM/dd/yyyy}", p.Where(x => x.Created.Date.Equals(DateTime.Now.AddDays(id).Date)).FirstOrDefault().Created);

			return string.Empty;
		}

		private static void EfficientValidateSubmission(int id)
		{
			var p = (from item in data where item.ID.Equals(id) && item.Name.Contains(id.ToString()) && item.Created.Date.Equals(DateTime.Now.AddDays(id).Date) select item).FirstOrDefault();

			if (p != null)
			{
				Console.WriteLine("Found ID in set = {0}", p.ID);
				Console.WriteLine("Found Name in set = {0}", p.Name);
				Console.WriteLine("Found Date in set = {0:MM/dd/yyyy}", p.Created);
			}
		}

		private static SomeObject GetSpecificRecord(int id)
		{
			return (from item in data where item.ID.Equals(id) select item).SingleOrDefault();
		}
	}

	class SomeObject
	{
		public int ID { get; set; }
		public string Name { get; set; }
		public DateTime Created { get; set; }
		public bool IsActive { get; set; }
	}
}

Open in new window

Produces the following output -Capture.JPG-saige-
0
 
LVL 7

Author Comment

by:Camillia
ID: 40534249
Thanks. I'll  change the code and review your examples
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…

661 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question