Should table Indexing be Faster?

Example code.
t = combinations(0:10,0:10,0:10,0:10);
tic
for ii = 1:10
for jj = 1:height(t)
u = t{jj,:};
end
end
toc
Elapsed time is 18.111169 seconds.
tic
tcell = table2cell(t);
for ii = 1:10
for jj = 1:height(tcell)
u = [tcell{jj,:}];
end
end
toc
Elapsed time is 0.179943 seconds.
tic
tarr = table2array(t);
for ii = 1:10
for jj = 1:height(tarr)
u = tarr(jj,:);
end
end
toc
Elapsed time is 0.017899 seconds.
Any ideas why indexing into a table to extract data is so slow?

2 件のコメント

Walter Roberson
Walter Roberson 2024 年 9 月 15 日
By the way: we held a discussion of table indexing across rows, about two-ish years ago. I know that I contributed, and I seem to remember that Steven Lord contributed. The thread revived briefly a couple of months ago. Unfortunately I do not seem to be able to locate it at the moment.
Paul
Paul 2025 年 9 月 15 日
No change in 2025a
t = combinations(0:10,0:10,0:10,0:10);
tic
for ii = 1:10
for jj = 1:height(t)
u = t{jj,:};
end
end
toc
Elapsed time is 18.246674 seconds.

サインインしてコメントする。

 採用された回答

Matt J
Matt J 2024 年 9 月 16 日
編集済み: Matt J 2024 年 9 月 16 日

1 投票

I haven't profiled it, but I would bet that the following line, from @tabular/braceReference
b = t.extractData(varIndices);
is bottlenecking the row extraction operations. Effectively, this runs table2array(t) on the entire table t every time a braceReferencing operation is done.
That probably should be done differently, since as a result, the time for even the smallest row-extraction operation is a very strong function of the size of the table, see example below:
T = combinations(1:100,1:100,1:40,1:40);
t=T(1,:);
timeit(@() t{1,:})
ans = 1.4134e-04
timeit(@() T{1,:})
ans = 0.2923

6 件のコメント

Matt J
Matt J 2024 年 9 月 16 日
I have now reported this to Tech Support.
Paul
Paul 2024 年 9 月 17 日
Thanks for your inputs and discussion. If you don't mind, please post back here with their response.
Paul
Paul 2024 年 9 月 17 日
If I understand correctly, then column extraction should also be a function of the size of the table (assuming table2array inside extractData works the same for a wide table as it does for a tall table). But it isn't.
T = combinations(1:100,1:100,1:40,1:40);
T = array2table(table2array(T).');
size(T)
ans = 1×2
4 16000000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
t=T(:,1);
timeit(@() t{:,1})
ans = 3.6526e-05
timeit(@() T{:,1})
ans = 2.8859e-05
Does braceReference() work differently when extracting columns?
Matt J
Matt J 2024 年 9 月 17 日
編集済み: Matt J 2024 年 9 月 18 日
Yes, once again if we look at the line,
b = t.extractData(varIndices);
we see that extractData() uses varIndices. This is used to discard columns that aren't being referenced, and does so before any data copying is done. This greatly reduces the overhead. It ought to be doing the same with the rows, but it isn't.
Matt J
Matt J 2024 年 9 月 18 日
編集済み: Matt J 2024 年 9 月 18 日
From Tech Support:
Thank you for identifying a performance slowdown when extracting rows from a table. My colleagues are aware of the issue and are working on a fix. In the meantime, a workaround is to use parenthesis subscripting.
For example, currently you are extracting rows using the following syntax. Instead, extract rows using parentheses.
T = combinations(1:100,1:100,1:40,1:40);
t = T(1,:);
When I compared the elapsed time for both these syntaxes, the suggested workaround of parentheses was significantly faster than the original.
%Original example
tic, for i = 1:100, t1 = t{1,:}; end, toc
Elapsed time is 0.005140 seconds.
tic, for i = 1:100, t1 = T{1,:}; end; toc
Elapsed time is 4.458811 seconds.
% Workaround
tic, for i = 1:100, t1 = t(1,:); t1 = t1.Variables; end, toc
Elapsed time is 0.006460 seconds.
tic, for i = 1:100, t1 = T(1,:); t1 = t1.Variables; end; toc
Elapsed time is 0.005319 seconds.
Paul
Paul 2024 年 9 月 18 日
Just want to point out that creating the temporary variable (t1 in this case) isn't necessary if the result is to be used directly, like as an input to a function
T = combinations(1:100,1:100,1:40,1:40);
T(1,:).Variables
ans = 1×4
1 1 1 1
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Also, perhaps MathWorks should consider a near term update to use this exact workaround in rowfun when it's called with SeparateInputs=false

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeMultidimensional Arrays についてさらに検索

製品

リリース

R2024b

質問済み:

2024 年 9 月 15 日

コメント済み:

2025 年 9 月 15 日

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by