以下是一些提高 Octave 程序执行速度的其他方法。
a = zeros (1000); # 创建一个 1000x1000 的矩阵 b = a; # 此处不进行复制 b(1) = 1; # 此处才进行复制
惰性复制适用于整个 Octave 对象,如矩阵、元胞数组、结构体,以及单个元胞或结构体元素(但不适用于数组元素)。
此外,当 Octave 能够确定索引部分在内存中是连续的时,索引表达式也会使用惰性复制。例如:
a = zeros (1000); # 创建一个 1000x1000 的矩阵 b = a(:,10:100); # 此处不进行复制 b = a(10:100,:); # 此处才进行复制
这适用于使用 ‘()’ 进行索引的数组(矩阵)、元胞数组和结构体。生成逗号分隔列表的索引表达式在某些情况下也可以受益于浅复制。特别是,当 a 是一个结构体数组时,像 {a.x}、{a(:,2).x} 这样的表达式将使用惰性复制,从而在结构体数组和元胞数组之间共享数据。
大多数索引表达式的生命周期不会超过其父对象。然而,在极少数情况下,惰性复制的切片会比其父对象存活更久,此时它会变成"孤儿",仍然占用不必要的内存。为了在大多数实际情况下提供补救措施,Octave 会在某些情况下检查孤立的惰性切片——当一个值被存储到"永久"位置(例如命名变量、元胞或结构体元素)时——并尽可能对它们进行优化。例如:
a = zeros (1000); # 创建一个 1000x1000 的矩阵
b = a(:,10:100); # 惰性切片
a = []; # 原始数组 "a" 仍然被分配
c{1} = b; # 此时 b 被重新分配
result = zeros (big_n, big_m) for i = over:and_over ridx = ... cidx = ... result(ridx, cidx) = new_value (); endfor
而不是:
result = []; for i = ever:and_ever result = [ result, new_value() ]; endfor
有时项目的数量无法预先计算,需要进行类似栈的操作。当元素被重复地从数组末尾插入或移除时,Octave 会将其识别为栈的使用,并尝试通过以更大的块预分配数组来使用更智能的内存管理策略。此策略同样适用于元胞数组和结构体数组。
a = []; while (condition) ... a(end+1) = value; # "压栈"操作 ... a(end) = []; # "出栈"操作 ... endwhile
eval 或 feval。解析输入或在符号表中查找函数名称都是相对昂贵的操作。
如果您只是将 eval 用作异常处理机制,而不是因为需要执行某些任意文本,请改用 try 语句。参见 try 语句。
ignore_function_time_stamp。如果您正在调用大量函数,并且在运行期间没有任何函数需要更改,请将变量 ignore_function_time_stamp 设置为 "all"。这将阻止 Octave 在程序运行时检查函数文件的时间戳以查看其是否已被更新。版权所有 © 2024-2026 Octave中文网
ICP备案/许可证号:黑ICP备2024030411号-4