Slow 2020a循环写表的性能

12次浏览(最近30天)
查尔斯·斯文森
查尔斯·斯文森 2020年5月14日
编辑: 剪秋罗属植物龙 2020年7月22日
我遇到了一个使用表的问题,因为写表要花很多时间,以至于使用表变得不可行。 我通过创建一个结构并使用struct2table()加载表,使用小~1000行写入表来开发应用程序。当我移动到10^6行时,我期望时间是线性的,但发现指数的缩放使应用程序无法使用。
我开发这段示例代码是为了帮助说明这个问题。我发现,当使用for循环时,写入一个大的(10^6)行表的分段会随着所写入的行数呈指数级增长。显然,struct2table()函数也有类似的问题。
清晰的所有
var = {' a ' ' b ' ' c ' ' d '};
varType = {'double' 'double' 'double' 'double'};
Rows = [100 1000 10000 100000 200000 300000 400000 500000];
d1 = 0(大小(行));d2 = 0(大小(行));
i = 1:长度(行)
T =表(“大小”, (1) e6、长度(var)),“VariableNames”var,“VariableTypes”, varType);
抽搐
肺结核(1:行(i)) =兰德([行(i), 1]);
d1 (i) = toc;
流('1)向量写入%。0f行接受%。4 f秒\ n”行(i), d1 (i));
抽搐
j = 1:行(我)
T.A (j) =兰德;
结束
d2 (i) = toc;
流('2)循环写入%。0f行接受%。4 f秒\ n \ n”行(i), d2 (i));
结束
数字
重对数(行,[d1;d2)
传奇(“向量写”循环写的);
在我的Macbook上,我看到了这个:
1)向量写100行需要0.0077秒
2)循环写100行需要0.0190秒
1)向量写1000行需要0.0029秒
2)循环写1000行需要0.0916秒
1)向量写10000行需要0.0005秒
2)循环写10000行需要0.9005秒
1)向量写100000行花费0.0009秒
2)循环写100000行需要12.1660秒
1)向量写入200000行需要0.0021秒
2)循环写200,000行需要30.3729秒
1)向量写入300000行需要0.0024秒
2)循环写300000行需要67.7139秒
1)向量写40万行需要0.0030秒
2)循环写40万行需要161.0859秒
1)向量写入500000行需要0.0038秒
2)循环写500000行需要220.1511秒
我曾计划使用高表的应用程序,可能达到10^10行,所以任何建议,如何最好的方式写表的分段将受到赞赏。
1评论
Sindar
Sindar 2020年5月15日
我的建议是去测试一下高桌子。缩放是完全不同的也不是不可能的

登录评论。

答案(1)

剪秋罗属植物龙
剪秋罗属植物龙 2020年7月18日
编辑:剪秋罗属植物龙 2020年7月22日
你好查尔斯,
谢谢你提出这个性能问题。我假设从你的代码片段,计时是在基础工作空间(即直接在MATLAB命令窗口下)或作为一个脚本。
在base-workspace/script和函数之间存在着重要的、有时非常重要的性能暗示。例如,这里我把你的代码放在一个函数中:
函数SwensonTiming
var = {' a ' ' b ' ' c ' ' d '};
varType = {'double' 'double' 'double' 'double'};
Rows = [100 1000 10000 100000 200000 300000 400000 500000];
d1 = 0(大小(行));d2 = 0(大小(行));
i = 1:长度(行)
T =表(“大小”, (1) e6、长度(var)),“VariableNames”var,“VariableTypes”, varType);
抽搐
肺结核(1:行(i)) =兰德([行(i), 1]);注意,这也是计时rand()的大小缩放
d1 (i) = toc;
流('1)向量写入%。0f行接受%。4 f秒\ n”行(i), d1 (i));
抽搐
j = 1:行(我)
T.A (j) =兰德;
结束
d2 (i) = toc;
流('2)循环写入%。0f行接受%。4 f秒\ n \ n”行(i), d2 (i));
结束
数字
重对数(行,[d1;d2)
传奇(“向量写”循环写的);
请注意,您的代码和上面的函数(具有完全相同的代码)都在计时中包含rand(),尽管它对运行时没有任何重要贡献。
在我的~4年旧的Core-i5/16GB ram桌面,运行MATLAB R2020a Update 4,“循环写”部分按预期线性扩展-也显示了你的代码的plot(当在一个函数中)产生:
> > SwensonTiming
1)向量写100行需要0.0003秒
2)循环写100行需要0.0073秒
1)向量写1000行需要0.0003秒
2)循环写1000行需要0.0666秒
1)向量写10000行需要0.0005秒
2)循环写10000行需要0.6360秒
1)向量写100000行需要0.0023秒
2)循环写100000行需要6.8393秒
1)向量写入200000行需要0.0057秒
2)循环写200,000行需要14.4702秒
1)向量写入300000行需要0.0068秒
2)循环写300000行需要20.4186秒
1)向量写40万行需要0.0128秒
2)循环写40万行需要26.2447秒
1)向量写500000行需要0.0115秒
2)循环写500000行需要32.3546秒
当然,向量化仍然可以获得更好的性能,但是示例中的标量循环赋值可以按照预期进行扩展。
简而言之,利用函数(而不是基本工作区或脚本)中当前提供的最佳性能表。罗兰的博客发表了一篇 关于R2020a表性能的最新进展的有用帖子 ,以及一些用于性能的通用模式/反模式。
如果您的用例仍然遇到性能问题,请与我们联系。我们想更多地了解你们的工作流程。

社区寻宝

在MATLAB中心找到宝藏,并发现社区如何可以帮助你!

开始狩猎!