ref和range哪个性能更好?表格处理中的真实对比

ref和range哪个性能更好?

在处理大型电子表格时,尤其是用脚本自动化操作,比如用 Google Apps Script 或 VBA 写宏,经常会遇到选择使用 ref 还是 range 的问题。很多人以为这只是写法不同,其实背后对运行速度的影响差别不小。

先说结果:在大多数实际场景下,直接操作 range 比通过 ref 引用性能更好。原因在于 ref 通常是间接引用,多了一层解析过程,而 range 是直接定位单元格区域,执行更干脆。

一个真实例子:批量修改数据

假设你要更新 A1 到 A10000 这一列的值,把每个单元格的内容变成大写。如果用 ref 方式,可能会这样写:

const sheet = SpreadsheetApp.getActiveSheet();
const dataRange = sheet.getRange("A1:A10000");
const values = dataRange.getValues();

values.forEach((row, i) => {
  values[i][0] = row[0].toString().toUpperCase();
});

// 通过 ref 设置回去
sheet.getRange("A1:A10000").setValues(values);

这段代码没问题,但如果你反复调用 getRange("A1:A10000"),每次都会重新解析字符串,系统得去“翻译”这个地址。虽然一次看不出差别,但在循环或多个操作中,这种开销会叠加。

更高效的做法是,先把 range 存成变量,避免重复查找:

const sheet = SpreadsheetApp.getActiveSheet();
const targetRange = sheet.getRange("A1:A10000"); // 只解析一次
const values = targetRange.getValues();

values.forEach((row, i) => {
  values[i][0] = row[0].toString().toUpperCase();
});

targetRange.setValues(values); // 复用同一个 range 对象

这样做不仅减少了解析次数,还降低了内存中的对象创建频率,整体执行时间能缩短 20% 到 40%,尤其在老旧设备上更明显。

ref 的使用场景并不全坏

ref 在某些动态场景下仍有优势。比如你写一个通用模板,公式里用 INDIRECT("Sheet"&A1&"!B1") 这类 ref 引用,能灵活切换工作表。但这属于公式层面的动态需求,不适合高频操作。

再比如,你在写一个配置驱动的报表系统,某个单元格存的是数据区域名称(如“SalesQ1”),然后用 ref 去读取对应区域。这时候用 ref 是合理的,毕竟灵活性优先。

但一旦进入批量处理、循环更新这类性能敏感的环节,就该换成预定义的 range 操作。

小技巧:减少 getRange 调用次数

很多人习惯每次要用就写一次 getRange,其实可以提前缓存。比如你要同时改 A 列和 B 列:

const sheet = SpreadsheetApp.getActiveSheet();
const rangeA = sheet.getRange("A1:A10000");
const rangeB = sheet.getRange("B1:B10000");

const valuesA = rangeA.getValues();
const valuesB = rangeB.getValues();

// 处理逻辑...

rangeA.setValues(valuesA);
rangeB.setValues(valuesB);

虽然写了两次 getRange,但只各一次,没有在循环里反复调用。比用 ref 字符串拼接再解析要快得多。

如果你发现脚本运行越来越慢,特别是数据量上来之后卡顿明显,不妨检查一下是不是到处都在用字符串形式的 ref 定位区域。换成直接 range 操作,往往会有意外之喜。