2

关于函数属性以及父函数的编译@safe时和运行时性能,构造字符串的首选方法是什么?purenothrow

例如,我们是否应该使用

format("Variable x=%s should equal %s", x, x_)

或者

"Variable x=" ~to!string(x)~ " should equal " ~to!string(x_)

我认为该format版本在视觉上更容易,但在其他方面更好吗?

由于格式字符串及其参数必须是 CTFEed,因此编译时间可能会对性能产生轻微影响,对吗?

4

2 回答 2

1

第一个版本通常更好。编译性能没有显着差异(如果有的话,format 不是 ctfe),format() 实际上应该表现更好。

二进制“foo”~“bar”通常非常昂贵,因为它分配了垃圾收集器必须清理的中间结果。

在我拥有的 dmd 版本上,这两个版本实际上都无法编译为安全的、非抛出的、纯的。我认为他们在 phobos git 中解决了这个问题,但我不确定。无论如何,现在两者都不起作用,除了实现自己的功能之外没有简单的解决方法,除非它只是用于调试。

在调试语句中放宽了纯要求,您可以在@system 中包装非@safe 函数,并在try/catch 中抛出函数以获取这些属性。

因此,这实际上会编译:

// trusted gets around safe
@trusted pure nothrow string myformat(T...)(in string fmt, in T t) {
import std.string;
    // debug gets around the pure requirement
debug try // try gets around nothrow
    return format(fmt, t);
catch(Exception e) { }

return null;
}

@safe nothrow pure void main() {
import std.conv;
string s = myformat("test %s", 10);
    assert(0, s); // the assert message shows up
}

使用 -debug 开关编译:dmd test.d -debug

所以不是一个很好的解决方案,但是直到释放具有适当属性的 phobos 函数,或者如果你想编写自己的 format() 或 to() 函数(不是那么难,你可以在 < 10 行中对字符串执行 int ) 可能是你能做的最好的。

于 2013-09-01T22:46:34.933 回答
0

正如接受的答案所说,preferformat!和 prefer 将格式字符串作为模板参数传递:

#!/usr/bin/env rdmd

module test;

import std.format; // or std.string, which publicly imports std.format
import std.stdio;

void main()
{
    writeln(format("%s%s","run-time error 'Orphan format specifier'"));
    writeln(format!"%s%s"("compile-time error 'Orphan format specifier'"));
}

它自2017 年 4 月发布的DMD 2.074.0起可用。

于 2018-08-23T09:16:23.900 回答