假设我们有一个结构体,它有一个名为 idx 的 int 字段。我有这个结构的列表,我需要生成一个不在这个列表中的索引。最直接的保留是:gen idx keep { it not in mylist.idx; };
问题是如果 mylist 很长,那么 mylist.idx 我们会返回一个大列表。我宁愿这样做: gen idx keep { not mylist.has(it.idx == it); };
有没有其他方法可以做到这一点,具有更好的内存性能?
假设我们有一个结构体,它有一个名为 idx 的 int 字段。我有这个结构的列表,我需要生成一个不在这个列表中的索引。最直接的保留是:gen idx keep { it not in mylist.idx; };
问题是如果 mylist 很长,那么 mylist.idx 我们会返回一个大列表。我宁愿这样做: gen idx keep { not mylist.has(it.idx == it); };
有没有其他方法可以做到这一点,具有更好的内存性能?
实际上,当 list.field 返回一个新列表时,并且重复执行此操作时,可以分配大量内存。
减轻痛苦的一种方法是使用辅助列表来避免使用“mylist.idx”和分配新列表。
这样,如果您的原始代码是
<'
struct A {
idx:int;
};
extend sys {
run() is also {
var mylist: list of A;
var idx:int;
for i from 0 to 10000 {
gen idx keeping {it not in mylist.idx};
mylist.add(new A with {.idx = idx;});
};
};
};
'>
峰值进程大小:969MB
您可以添加一个辅助列表:
<'
struct A {
idx:int;
};
extend sys {
run() is also {
var mylist: list of A;
var l : list of int;
var idx:int;
for i from 0 to 10000 {
gen idx keeping {it not in l};
mylist.add(new A with {.idx = idx;});
l.add(idx);
};
};
};
'>
峰值进程大小:736MB
但是,从 Specman 12.2 开始,您可以将“set”类型与辅助变量一起使用,这在生成时更有效。
<'
struct A {
idx:int;
};
extend sys {
run() is also {
var mylist: list of A;
var S:set;
var idx:int;
for i from 0 to 10000 {
gen idx keeping {it not in value(S)};
mylist.add(new A with {.idx = idx;});
S = S.union([idx]);
};
};
};
'>
峰值进程大小:135MB