I once went to a company interview, encountered such a topic: ask for the number of primes within 1000 how many? Use multithreading to achieve, and give time to consume. I thought for a while and didn't come up with a multi-threaded solution. Today because of the opportunity, I talk about my solution.
This problem obviously has to consider two questions:
1, multi-threaded issues
2, algorithm performance problems
Some people think what algorithm performance is considered within 1000? It must be quick. But then again, is it necessary to use multithreading? How many are there if we ask for a prime number within 10000000? Do you have to consider the above two questions? The purpose of multithreading and algorithm optimization is to improve the efficiency of program execution. Let's consider the algorithm problem first, what is prime number? Primes: Also known as prime numbers, except for 1 in the natural number and itself, no other number can be divisible, and 1 is not prime. For example, 2, 3 are prime numbers. OK, let's look at the code:
1 Private Static BOOLISSUSHU1 (intN)2 {3 BOOLIssuflag =true;4 if(N <=1)return false;5 6 for(inti =2; I < n; i++)7 {8 if(n% i = =0)9 {TenIssuflag =false; One Break; A } - } - returnIssuflag; the}
This is the algorithm to find a number is not a prime, the algorithm according to the definition, if faced with tens data, directly out of the results. Can we optimize it? The answer is yes, so the math is good, for the computer workers, is always beneficial to the harmless, we look at the improved code:
1 Private Static BOOLIssushu (intN)2 {3 BOOLIssuflag =true;4 if(N <=1)return false;5 6 7 for(inti =2; I <= (int) Math.sqrt (Double) n); i++)8 {9 if(n% i = =0)Ten { OneIssuflag =false; A Break; - } - } the returnIssuflag; -}
The code does not change greatly, just the number of cycles of large-scale reduction, think, if it is millions data, open a square root, it becomes 1000 level. The principle of this algorithm, not to understand, is seen from the Internet, in short, is a real mathematical problem, if the mathematical thinking is very good, this estimate can be obtained.
Algorithm has, then what are the problems with multithreading?
First, we have to get the results of each thread execution. Second, the total consumption time is calculated. To create a thread, we can create it directly with thread, but the thread creates a comparison of consumption performance and does not take the result. If you create a background thread with ThreadPool, the performance is improved, or the results of the thread execution are not directly available. I then thought of the task in C #. Task knowledge points More, you can learn slowly. First look at the implementation:
1 Private Static voidMultithreadcompute (intNintpageSize)2 {3list<task<int>> tasks =Newlist<task<int>>();4 5 varStart =DateTime.Now;6 7 for(inti =1; I <= n/pagesize; i++)8 {9 varPageIndex =i;Ten intStartnum = (PageIndex-1) *pageSize; One intEndnum = Startnum +pageSize; A - int[] numbers ={startnum, endnum}; - theTasks. Add (Task.Factory.StartNew (obj) = - { - intTotalCount =0; - + int[] temps = obj as int[]; - + for(intj = temps[0]; J < temps[1]; J + +) A { at if(ISSUSHU1 (j)) - { -totalcount++; - } - } - returnTotalCount; in }, numbers)); - } to +Task.Factory.ContinueWhenAll (tasks. ToArray (), (taskList) = - { the varEnd =DateTime.Now; * intresult =0; $ Panax Notoginseng foreach(varIteminchtasks) - { theResult + =item. Result; + AConsole.WriteLine ("task{0} found {1} primes", item. Id, item. Result); the } + -Console.WriteLine ("{ 1} primes found within {0}, total time spent: {2}", N, result, end. Subtract (Start). totalseconds); $ $});
Explain the code, pagesize is I borrowed the page on the page of the algorithm, each thread executes a page of data. Starting with 32 lines, this is when all the tasks are completed, and then the loop task gets the result, which is also an asynchronous call that does not block the continuation of the main program. This can also be changed to synchronous invocation:
1 Task.waitall (tasks. ToArray ());2 3 intresult =0;4 5 foreach(varIteminchtasks)6 {7Result + =item. Result;8 9Console.WriteLine ("task{0} found {1} primes", item. Id, item. Result);Ten } One AConsole.WriteLine ("{ 1} primes found within {0}", n, result);
The WaitAll method of the task, blocks the main thread, and so on when all tasks are completed, the main thread begins to count the results.
The first line is the result of single-threaded execution, when 1.7s, the following is the result of multi-threaded execution, because it is an asynchronous call to get the results of the task execution, so the main thread first output "I am asynchronous call", in fact, this line of code in the last line.
This is a synchronous call, multi-threaded time spent more than the asynchronous call 0.1s, is not accidental? I run multiple times in a row, all at the 0.8s level, and asynchronous calls at the level of 0.7s. It seems to be a little faster. These two run results are based on the prime number definition algorithm, then I use the improved algorithm to see what the situation.
Everyone has not noticed, at this time the advantage of multithreading did not play out, it and single-threaded is 0.02s, then we add the amount of data to millions, see the results:
Just opened the 0.4s Gap, we put the data to tens, and then look at the results:
At this point, although multithreading than single-threaded save half the time, but still have 6s, increase the number of threads:
I added so many threads, only to improve the nearly 2s, pay and harvest is not proportional to ah. It turns out that the more threads are not necessarily the better, the more appropriate number of threads can be calculated so that less resources are spent and the best effort is made to improve performance.
An interview question: How many times do you use multithreading to find the prime number within 1000? And give the time to consume