0

我找到了一个 osrm-machine,它在我请求时返回一个 json 字符串。json 有一些关于 2 个位置的特殊信息,我正在处理 json 并获取距离属性的值,以构建这些位置的距离矩阵。我有超过 2000 个位置,这个处理大约需要 4 个小时。我需要通过并行减少执行时间,但我对这个话题很陌生。这是我的工作,我应该如何优化并行循环?或者也许你可以让我采用新的方法。谢谢

 var client = new RestClient("http://127.0.0.1:5000/route/v1/table/");
            var watch = System.Diagnostics.Stopwatch.StartNew();

            //rawCount = 2500
            Parallel.For(0, rowCount, i =>
            {
                Parallel.For(0, rowCount, j =>
                {
                    //request a server with spesific lats,longs
                    var request = new RestRequest(String.Format("{0},{1};{2},{3}", le.LocationList[i].longitude, le.LocationList[i].latitude,
                                                                                                        le.LocationList[j].longitude, le.LocationList[j].latitude));

                    //reading the response and deserialize into object
                    var response = client.Execute<RootObject>(request);

                    //defining objem with the List of attributes in routes
                    var objem = response.Data.routes;

                    //this part reading all distances and durations in each response and take them into dist and dur matrixes.
                    Parallel.ForEach(objem, (o) =>
                    {
                        dist[i, j] = o.distance;
                        dur[i, j] = o.duration;
                        threads[i,j] =  Thread.CurrentThread.ManagedThreadId;
                        Thread.Sleep(10);

                    });
                });
            });

        watch.Stop();
        var elapsedMs = watch.ElapsedMilliseconds;
4

1 回答 1

0

我清理了一下。使用并行性就足够了。您仍然需要查看一个循环,因为它正在覆盖数据,我不知道如何处理它,这是您的决定。

您需要稍微尝试一下maxThreads变量的值。通常,.NET 会启动足够多的线程,以便您的处理器可以处理它们,在您的情况下,您可以启动更多线程,因为您知道所有线程都只是空闲等待网络堆栈。

using System;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp7
{
    class Program
    {
        static void Process(int i, int j)
        {
            var client = new RestClient("http://127.0.0.1:5000/route/v1/table/");

            //request a server with spesific lats,longs
            var request = new RestRequest(String.Format("{0},{1};{2},{3}", le.LocationList[i].longitude, le.LocationList[i].latitude, le.LocationList[j].longitude, le.LocationList[j].latitude));

            //reading the response and deserialize into object
            var response = client.Execute<RootObject>(request);

            //defining objem with the List of attributes in routes
            var objem = response.Data.routes;

            //this part reading all distances and durations in each response and take them into dist and dur matrixes.

            // !!! 
            // !!! THIS LOOP NEEDS TO GO. 
            // !!! IT MAKES NO SENSE!
            // !!! YOU ARE OVERWRITING YOUR OWN DATA!
            // !!!
            Parallel.ForEach(objem, (o) =>
            {
                dist[i, j] = o.distance;
                dur[i, j] = o.duration;
                threads[i, j] = Thread.CurrentThread.ManagedThreadId;
                Thread.Sleep(10);
            });
        }

        static void Main(string[] args)
        {
            var watch = System.Diagnostics.Stopwatch.StartNew();

            var rowCount = 2500;
            var maxThreads = 100;

            var allPairs = Enumerable.Range(0, rowCount).SelectMany(x => Enumerable.Range(0, rowCount).Select(y => new { X = x, Y = y }));

            Parallel.ForEach(allPairs, new ParallelOptions { MaxDegreeOfParallelism = maxThreads }, pair => Process(pair.X, pair.Y));

            watch.Stop();

            var elapsedMs = watch.ElapsedMilliseconds;
        }
    }
}
于 2017-05-12T13:14:50.333 回答