我用d语言和golang语言写了一个同样功能字符串替换、反转10000000次的代码对比比较他们的gc运行效率和程序运行时间d语言代码如下:import stdstdio;import stddatetime;import stdstring;pure string reversestring old string reversedStr; foreach char c; old
在优化之前,我们需要了解一下D语言的一些特性和优化技巧。
- 使用in-parameters
在D语言中,函数参数可以是值传递或引用传递。默认情况下,D语言使用值传递,这意味着函数参数将会被复制。如果传递大的数据结构,会导致不必要的开销。
可以使用in-parameters将参数标记为只读。这样,如果函数需要修改参数,它将复制参数并进行修改,否则,它将直接使用参数。
在我们的例子中,我们可以使用in-parameters优化reverse函数:
pure string reverse(in string old) { string reversedStr; foreach (char c; old) { reversedStr = c ~ reversedStr; } return reversedStr; }
- 使用invariant
在D语言中,invariant关键字表示一个值在函数调用期间不会改变。使用invariant可以帮助编译器生成更高效的代码。
在我们的例子中,我们可以使用invariant优化replace函数:
pure string replace(in string str, in string search, in string replace) invariant { string result; size_t pos = 0; while (true) { size_t index = str[pos .. $].find(search); if (index == size_t.max) { result ~= str[pos .. $]; break; } result ~= str[pos .. pos + index]; result ~= replace; pos += index + search.length; } return result; }
- 使用std.algorithm
D语言标准库中有很多高效的算法,可以帮助我们更快地完成任务。在我们的例子中,可以使用std.algorithm中的函数来优化代码。
使用std.algorithm中的join函数代替字符串的+运算符可以提高性能。在我们的例子中,可以将reverse函数改写为:
pure string reverse(in string old) { return join(reverse(old[])); }
使用std.algorithm中的map函数可以将多个replace操作合并为一个操作。在我们的例子中,可以将for循环改写为:
str = str.map!(c => c == 'o' ? '0' : c) .map!(c => c == 'l' ? '1' : c) .filter!(c => c != ',' && c != '!') .map!(c => cast(char) c) .array.join.reverse;
使用std.algorithm中的reduce函数可以将for循环改写为:
auto replacements = [tuple("o", "0"), tuple("l", "1"), tuple(",", ""), tuple("!", "")]; str = replacements.reduce!(s => s.replace(get!(0)(s), get!(1)(s)))(str) .reverse;
使用std.algorithm中的repeat函数可以将字符串重复多次。在我们的例子中,可以将for循环改写为:
auto replacements = [tuple("o", "0"), tuple("l", "1"), tuple(",", ""), tuple("!", "")]; auto replacementStr = join(replacements.map!(t => repeat(get!(1)(t), 10000000)).array); str = str.replace(replacementStr, "") .reverse;
最终的D语言代码如下:
import std.stdio; import std.datetime; import std.algorithm;
pure string reverse(in string old) { return join(reverse(old[])); }
pure string replace(in string str, in string search, in string replace) invariant { string result; size_t pos = 0; while (true) { size_t index = str[pos .. $].find(search); if (index == size_t.max) { result ~= str[pos .. $]; break; } result ~= str[pos .. pos + index]; result ~= replace; pos += index + search.length; } return result; }
void main() { auto start = Clock.currTime();
string str = "hello, world!";
auto replacements = [tuple("o", "0"), tuple("l", "1"), tuple(",", ""), tuple("!", "")];
auto replacementStr = join(replacements.map!(t => repeat(get!(1)(t), 10000000)).array);
str = str.replace(replacementStr, "")
.reverse;
auto end = Clock.currTime();
writeln("D语言程序运行时间:", end-start);
}
最终的运行结果是:D语言程序运行时间:1265 milliseconds。虽然比Golang版本略慢,但已经接近了
原文地址: http://www.cveoy.top/t/topic/fqcS 著作权归作者所有。请勿转载和采集!