这是一个几乎是学术问题,但我很好奇它的答案。
假设您有一个循环,它在数据集中的每一行上执行例程替换。假设有10,000行这样的行。
拥有这样的东西会更有效率:
Row = Row.Replace('X', 'Y');
或者检查行是否包含首先要替换的字符,如下所示:
if (Row.Contains('X')) Row = Row.Replace('X', 'Y');
效率方面有什么不同吗?我意识到差异可能非常小,我有兴趣知道一种方式是否优于另一种方式,无论它有多好。另外,如果找到要被替换的角色的概率是10%,那么你的回答会有所不同吗?
答案 0 :(得分:10)
对于您的检查,Row.Contains('X')
是一个O(n)函数,这意味着它一次遍历整个字符串一个字符以查看该字符是否存在。
Row.Replace('X', 'Y')
的工作方式完全相同,它一次检查每个字符一个字符。
因此,如果您已经进行了检查,则可能会对字符串进行两次迭代。如果只是替换,则迭代字符串一次。
答案 1 :(得分:1)
您需要先在真实数据集上进行测量,然后确定哪个性能更高。如果您的典型数据集通常没有任何内容,那么Contains()
调用可能会更快(因为虽然Replace
也遍历字符串中的所有字符,但会创建一个额外的字符串对象并且垃圾由于字符串的不变性而收集了,但如果经常出现“X”,那么支票就变成了浪费,实际上减慢了速度。
此外,这通常不是第一个寻找并担心性能问题的地方。像聊天界面,网络I / O,Web服务,数据库,文件I / O和GUI更新这样的事情会比这样的事情伤害你的数量级。
如果你打算做这样的事情,如果Row
从数据库回来(顾名思义),那么让数据库进行查询可能是另一种方法以节省性能。 E.g。
select MyTextColumn from MyTable where MyTextColumn like '%X%'
然后对所有结果执行替换,因为您知道只返回了需要替换的结果。
这确实引入了其他问题 - 例如,在SQL Server中,如果上面的示例包含MyTextColumn
上的索引,则SQL Server将无法使用该索引,因为like
参数以通配符开头(它不被认为是“sargable”)。
总之,首先编写正确性,可读性和维护性,然后测量性能并在需要的地方进行有针对性的改进。
答案 2 :(得分:0)
第一种选择更快。为了检查子串是否存在,首先必须找到它。由于没有任何缓存机制,为什么不直接替换它?否则你会搜索两次。如果“X”多次出现,那么你的工作量就会增加一倍。
答案 3 :(得分:-1)
不要忘记C#中的字符串是IMMUTABLE。这意味着他们无法改变。
为了替换它必须在内存中创建一个新字符串,并复制数据,然后垃圾收集旧字符串。
首先使用Contains(),可以防止对字符串数据进行不必要的创建,复制和垃圾收集,从而加快执行速度。