MATLAB的博客

实用的建议在前沿的人

在MATLAB部分排序

我最近与一位研究员排序数组双精度数成千上万次。然而在他的申请,他不需要完整的排序列表。他只是想要最低的 N / 2 数组的元素排序。因此,他有两个问题。
  • MATLAB有部分排序功能吗?
  • 他们会更快的为他的应用程序吗?
第一个问题的答案是很容易的。MATLAB已经 貂(x, k) maxk (x, k) 找到最低或最高排序 k 从数组中元素 x 分别。
第二个问题的答案“部分排序会更快吗?”取决于 k 如您所料。让我们研究如何

多长时间一个完整的排序带相比,部分排序要求最小的10项?

我们创建一个100000个元素的数组双打
x =兰德(100000 1);
我将这个数组排序匹配300倍如何在用户的应用程序使用。当然,在真正的应用程序中,x每次迭代变化但我想隔离那种
抽搐
i =施用
y = (x);
res = y (1:10);%我们只需要最低的10
结束
sortTime = toc
sortTime = 0.5181
如果我们想要的是10 x的最小的数字排序,我们或者可以使用
抽搐
i =施用
res =貂(x, 10);
结束
partialsortTime = toc
partialsortTime = 0.0361
流(“部分排序是%外汇速度比全k = 10”sortTime / partialsortTime)
部分是14.354572倍的速度比全k = 10
如您所料,部分排序是非常有用的,当你只需要少量的排序元素从一个大数组

部分排序总是比完整的排序吗?

接下来,我使用了 功能要求最低的k数k的变化从100年到15000年,和之前一样,我重复每个排序操作300次。
minkResults = 0 (150 1);
minkSize = 0 (150 1);
j = 1:15 0
抽搐
i =施用
y =貂(x, j * 100);
结束
minkResults (j) = toc;
minkSize (j) = j * 100;
结束
策划的结果,我们看到部分排序只是比一个完整的排序如果我们请求少于4200个元素,这是不到5%的全矢量。
情节(minkSize minkResults,“。”)
yline (sortTime)
传奇(“部分”,“全部”)
包含(“部分请求的数量”)
ylabel (“时间(s)”)
标题(“时间”+ +元素个数(x)“元素300倍”)
穿越= minkSize (find (minkResults > sortTime 1“第一”));
流(“x % d大小,貂皮(x, k)是速度比(x)只有在k < % d}”元素个数(x),穿越)
x 100000大小,貂皮(x, k)是速度比(x)只有在k < 4200}

为什么不是部分排序更好?

你可能会对这个结果感到失望,因为,至少在这个例子中,部分排序只是更好的选择如果你想要排序的元素总数的不到5%。主要的原因是 MATLAB的函数是快速和多线程。 很难打!
让我们看看 与100000年尺度元素排序 。我重复计算得到一个稳定的平均水平的300倍。
%的比例对线程
arraySize = 100000;
重复= 300;
sortSpeedTest (arraySize,重复)
ans = 4×3表
numThreads averageTime 加速
1 1 0.0052 1
2 2 0.0028 1.8151
3 4 0.0018 2.8250
4 8 0.0015 3.5265
中使用的算法 功能,另一方面,不适合多线程。因此,它完全是单线程的。看看这个贵族使用相同大小的输入矩阵,要求最低的10000数字进行排序。
%的比例貂对线程
k = 10000;
minkSpeedTest (arraySize、重复、k)
ans = 4×3表
numThreads averageTime 加速
1 1 0.0037 1
2 2 0.0037 0.9967
3 4 0.0037 1.0018
4 8 0.0036 1.0197
很显然,貂并没有受益于不同数量的线程。我们看到的不同只是测量噪声。如果 排序(x) 没有mulithreaded, 貂(x, k) 会更快但是多线程可以帮助很多。
当我们增加k,甚至最终会有一个地方比较单线程 排序 结果 失去。在我的机器上,k = 16000
%的比例貂对线程
k = 16000;
minkSpeedTest (arraySize、重复、k)
ans = 4×3表
numThreads averageTime 加速
1 1 0.0053 1
2 2 0.0053 1.0141
3 4 0.0054 0.9917
4 8 0.0053 1.0129
略低于单线程 排序 !一个可能的未来enhacement MATLAB 函数将切换到使用 排序 内部为大 k 因为,迟早 算法并不是正确的选择。

我的机器的信息

你可能会有不同的结果从我如果你在你的机器上运行这些测试。因此,一些信息关于我的机器可能是有用的。在这里,我使用的 本Tordoff cpuinfo函数 ,可用MATLAB文件交换。
cpuinfo
ans =结构体字段:
CPUName:“11日创英特尔(R) (TM)核心i7 - 11700 @ 2.50 ghz的钟:“2501 MHz的缓存:4194304 TotalMemory: 3.4010 e + 10 NumCPUs: 1 TotalCores: 8 OSType:“Windows”OSVersion:“Microsoft Windows 11 Pro”主机名:“DESKTOP-N3C7C6Q”

交给你了

总之,部分排序在MATLAB可以有用的,但是只有当适当使用。你使用 maxk 在你的工作…或have you just discovered them now? What additional sorting functionality do you think MATLAB should have?

辅助函数

函数结果= sortSpeedTest (arraySize,重复)
%运行排序的数组大小arraySize使用不同数量的线程
格式
averageTime = 0 (4,1);
加速= 0 (4,1);
numThreads = [1, 2, 4, 8];
兰德(x = 1, arraySize);
testNum = 1:4
线程= numThreads (testNum);
maxNumCompThreads(线程);
抽搐
我= 1:重复
y = (x);
结束
averageTime (testNum) = toc /重复;
加速(testNum) = averageTime (1) / averageTime (testNum);
结束
结果=表(numThreads averageTime,加速);
结束
函数结果= minkSpeedTest (arraySize、重复、k)
%貂运行在一个数组的大小arraySize使用不同数量的线程
格式
averageTime = 0 (4,1);
加速= 0 (4,1);
numThreads = [1, 2, 4, 8];
兰德(x = 1, arraySize);
testNum = 1:4
线程= numThreads (testNum);
maxNumCompThreads(线程);
抽搐
我= 1:重复
y =貂(x, k);
结束
averageTime (testNum) = toc /重复;
加速(testNum) = averageTime (1) / averageTime (testNum);
结束
结果=表(numThreads averageTime,加速);
结束
|

댓글

댓글을남기려면링크를클릭하여MathWorks계정에로그인하거나계정을새로만드십시오。