简体   繁体   English

倍频力深度复制

[英]Octave force deepcopy

The question 这个问题

What are the ways of coercing octave to create a real copy of whatever object? 强制八度创建任何对象的真实副本的方法是什么? Structures are the main interest. 结构是主要的兴趣所在。

My underlying problem 我的根本问题

In my problem I'm obtaining a rather large structure from another function in a loop but for the current task only a few pieces of it are needed. 在我的问题中,我从一个循环中的另一个函数获得了一个相当大的结构,但是对于当前任务,只需要其中的几个。 For example: 例如:

for i=1:many
    res=solver(params);
    store1{i}=res.string1;
    store2{i}=res.arr(:,1);
end

res is a sizable chunk of data and due to lazy-copy those store -s are references to tiny portions of bytes in that chunk. res是一个相当大的数据块,由于延迟复制,这些store -s引用了该数据块中字节的一小部分。 After I store those tiny portions, I don't need res itself, however, since middle of that chunk is referenced by store , the memory area is unfit for res obtained on the next iteration (they are of the same size) and thus another sizable piece of memory is allocated, which is then again crossed by few tiny links an so on. 在存储了这些微小的部分之后,我不需要res本身,但是,由于该块的中间被store引用了,因此内存区域不适合下一次迭代获得的res (它们具有相同的大小),因此另一个分配了相当大的内存,然后又被一些微小的链接交叉,依此类推。

Without storing parts of res, the program successfully keeps the memory consumption same after first couple of iterations. 在不存储部分res的情况下,该程序在前几次迭代后成功地使内存消耗保持不变。

So how do I make a complete copy of structure field? 那么,如何制作结构字段的完整副本? I've tried using struct -related functions like rmfield but those keep references instead of their own objects. 我尝试过使用与struct相关的函数(例如rmfield但是这些函数保留引用而不是它们自己的对象。 I've tried to wrap the assignment of in its own function: new_struct=copy( rmfield(old_struct,"bigdata")); 我试图将其分配包装在其自身的函数中:new_struct = copy(rmfield(old_struct,“ bigdata”)); function c=copy(a); 函数c = copy(a); c=a; C = A; end; 结束; This by the way doesn't work even for arrays. 顺便说一下,这甚至对于数组也不起作用。 I'm interested in method applicable to any generic variable. 我对适用于任何泛型变量的方法感兴趣。

Minimal working example of the problem 问题的最小工作示例

a=cell(3,1); 
for i=1:length(a); 
    r=rand(100000,1000);
    a{i}=r(1:100,end);
    whos; fflush(stdout);
    pause(2); 
end;

The above code will cause memory usage to gradually grow by far more than 8.08 kb reported by whos due to references stored by a{i} blocking bigger memory block than they actually need. 上面的代码将导致存储器使用逐步通过报道远远超过8.08 kb的生长whos由于由存储的引用a{i}阻断更大存储器块比实际需要的。 If you force the proper copy, the problem is not present. 如果强制使用正确的副本,则不会出现问题。

Numerical arrays 数值数组

For numeric types addition of zero is enough to warrant a new array. 对于数字类型,添加零就足以保证使用新数组。

c=a+0;

Strings 字符串

For string which is 1 xn char array, something along the following lines will work: 对于1 xn char数组的字符串,以下几行将起作用:

c=[a "a"](1:end-1);

Multidimensional char arrays will require concatenation with a column: 多维char数组将需要与列连接:

c=[a true(size(a,1),1)](:,1:end-1);  

Here true is used to generate dummy array of size compatible with char. 这里true用于生成大小与char兼容的伪数组。 (There seems to be no procedural method of generating char array of arbitrary size) char(zeros(size(a,1),1)) and char(true(size(a,1),1)) caused excess memory usage during their creation on some calls. (似乎没有生成任意大小的char数组的程序方法) char(zeros(size(a,1),1))char(true(size(a,1),1))导致在使用过程中过多的内存使用他们在某些电话上的创作。

Note that empty concatenation c=[a ""]; 请注意,空串联c=[a ""]; will not result in a copying. 不会导致复制。 Also it is possible to do c=[a+0 ""]; 也可以做c=[a+0 ""]; which will result in a copying due to +0 but that one infers type conversions to and from double which is 8 times larger in size. 这将导致由于+0而导致的复制,但是一个会推断出类型转换为double的大小是double的两倍。 ( char(zeros( doesn't seem to cause that) char(zeros(似乎不会导致这种情况)

Other types 其他种类

In general you can use casting for the types allowed by it in order to not tailor the expressions manually as I had to do above: 通常,您可以对它允许的类型使用强制类型转换 ,以免像我在上面所做的那样手动调整表达式:

typelist={"double","single","char"}; %full list of supported types is available in the link
class_of_a = typelist{ isa(a,typelist) };
c=typecast( [typecast(a,'single'); single(1)] (1:end-1), class_of_a);

Single is seemingly smallest datatype available in octave. Single似乎是八度中可用的最小数据类型。 Note that logical is not supported by this method. 请注意,此方法不支持逻辑。

Copying structures 复制结构

Apparently you'd have to write your own function to go around struct fields, copy them with above methods and recursively go to substructs. 显然,您必须编写自己的函数才能遍历struct字段,使用上述方法复制它们,然后递归地访问子结构。
(As it doesn't involve complexities relevant here, I'd rather leave that to be done by those who actually needs that, my own problem being solved by +0 's.) (由于这里不涉及相关的复杂性,我宁愿让那些真正需要它的人来完成,我自己的问题由+0来解决。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM