Performance 在Matlab中使用非连续整数作为单元格或结构中的标识符

Performance 在Matlab中使用非连续整数作为单元格或结构中的标识符,performance,matlab,struct,cell,identifier,Performance,Matlab,Struct,Cell,Identifier,我希望以以下方式存储一些结果: Res.0 = magic(4); % or Res.baseCase = magic(4); Res.2 = magic(5); % I would prefer to use integers on all other Res.7 = magic(6); % elements than the first. Res.2000 = 1:3; 我想使用介于0和3000之间的数字,但我只会使用大约100-300个。是否可以使用0作为标

我希望以以下方式存储一些结果:

Res.0 = magic(4);      % or Res.baseCase = magic(4);
Res.2 = magic(5);      % I would prefer to use integers on all other
Res.7 = magic(6);      % elements than the first.
Res.2000 = 1:3;
我想使用介于0和3000之间的数字,但我只会使用大约100-300个。是否可以使用0作为标识符,或者必须使用最小值1?(这些数字有意义,所以如果我不需要更改它们,我会更喜欢)。我可以在结构中使用数字作为标识符吗

我知道我可以做到以下几点:

Res{(last number + 1)} = magic(4);    
Res{2} = magic(5);
Res{7} = magic(6);
Res{2000} = 1:3;
记住最后一个元素实际上是“数字零”元素

在本例中,我将在未填充的位置创建一组空单元格元素
[]
。这会引起问题吗?我认为最好先指定最后一个元素,以避免创建一个正在生长的单元格,或者这不会产生影响?这是一种有效的方法吗

哪个是最有效的,
struct
还是
单元格
?(如果可以使用
struct
,也就是说)

我主要关心的是计算效率


谢谢

让我们回顾一下您的选项:

索引到单元格数组中 MATLAB索引从1开始,而不是从0开始。如果要将数据存储在单元格数组中,在最坏的情况下,可以始终使用下标
k+1
索引到与第k个标识符(k)对应的单元格中≥ 0). 在我看来,使用最后一个元素作为“基本情况”更容易混淆。因此,您将有:

Res{1} = magic(4);                   %// Base case
Res{2} = magic(5);                   %// Corresponds to identifier 1
...
Res{k + 1} = ...                     %// Corresponds to indentifier k
访问结构中的字段 结构中的字段名不允许以数字开头,但允许包含从第二个字符开始的字段名。因此,您可以这样构建您的结构:

Res.c0 = magic(4);                   %// Base case
Res.c1 = magic(5);                   %// Corresponds to identifier 1
Res.c2 = magic(6);                   %// Corresponds to identifier 2
%// And so on...
您可以使用访问任何字段,例如:

k = 3;
kth_field = Res.(sprintf('c%d', k)); %// Access field k = 3 (i.e field 'c3')
我说不出哪种方法看起来更优雅,但我相信在单元格中建立索引应该比动态字段引用更快(但欢迎您检查并证明我是错的)。

作为一种替代方法,它听起来似乎正是您所需要的。它们可以处理任何类型的键,值可以是
结构
单元格

编辑:

在您的情况下,这将是:

k = {0,2,7,2000};
Res = {magic(4),magic(5),magic(6),1:3};
ResMap = containers.Map(k, Res)

ResMap(0)    
ans =
16     2     3    13
 5    11    10     8
 9     7     6    12
 4    14    15     1

我同意@wakjah评论中的观点。如果您担心程序的效率,最好改变对问题的解释。在我看来,确实有一种方法可以对数据进行优先排序。这种优先顺序可以根据您获得它们的时间,或者根据计算出的输入来确定。如果在它们之间设置任何类型的优先级,则可以将它们排序到结构或单元中(结构可能更快)

所以

然后:


为什么不存储两个单元格数组,一个带有“索引”,另一个带有该索引处的数据?还是具有两列的单个单元格数组?还是有两个字段的结构数组?@wakjah。最重要的是,因为我没有想到它,我想=)我试图想象这将如何工作,但我真的不能这样做。我看不出会有什么不同。你能举个例子说明我如何用这种方式存储零元素吗?谢谢非常感谢你,伊坦!您知道我是否应该在开始之前设置单元格的大小,即
Res=cell(3000,1),类似于我在向量末尾插入元素的做法?或者这不会有任何影响,因为每个单元的大小无论如何都是未知的?预先分配内存总比让MATLAB动态增加数组的大小要好,因为后者通常要慢得多。我不能对速度(与Eitan的答案相比)说什么,但这绝对是我想要的!谢谢!!=)如果使用简单的键(如整数),映射将简化为简单数组。实际上没有必要过于复杂。@EitanT,您的方法在性能方面可能更好(只是稍微好一点)。另一方面,我认为使用
map
更容易理解。但是,只有当其他人需要使用相同的代码时,这才有意义。代码的一部分最终会被翻译成C(不是由我翻译),因此可读性是一个因素。我不知道C,但是如果我记得正确的话, map < /Cord>至少在C++中是这样工作的。(当然,在C中,我可以使用0作为索引,但是
map
似乎是一个很好的方法,尽管如此=)在这种情况下,我也建议在matlab中使用map容器。如果只计划使用~300个键,则使用贴图的性能损失可能可以忽略。任何C/C++程序员都会立即理解映射的功能。如果其他人的可读性很重要,我会说matlab的魔法越少越好(尽管@EitanT的技巧非常酷!)。谢谢@pm89!很抱歉迟了答复。我同意,这看起来是一个很好的方法=)+1!
Priority    (Your Current Index Meaning)    Data
   1        0                               magic(4)
   2        2                               magic(5)
   3        7                               magic(6)
   4        2000                            1:3
% Initialize Result structure which is different than your Res.
Result(300).Data = 0; % 300 the maximum number of data
Result(300).idx = 0; % idx or anything that represent the meaning of your current index.

% Assigning
k = 1; % Priority index
Result(k).idx = 0;    Result(k).Data = magic(4);    k = k + 1;
Result(k).idx = 2;    Result(k).Data = magic(5);    k = k + 1;
Result(k).idx = 7;    Result(k).Data = magic(6);    k = k + 1;
...