Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/458.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Javascript中避免调试代码降低运行时性能_Javascript_Debugging_Preprocessor - Fatal编程技术网

如何在Javascript中避免调试代码降低运行时性能

如何在Javascript中避免调试代码降低运行时性能,javascript,debugging,preprocessor,Javascript,Debugging,Preprocessor,我有一些对时间敏感的异步代码,只能通过记录实时数据然后查看日志来调试。因此,我用如下语句插入代码: DBG(`Setting ${name} timer for ${amount} ms from runMore(${reason})`); let debugOn = process.env["DEBUG_RATE_LIMIT_MAP"] === "1"; let DBG; if (debugOn) { DBG = function(...args) { args.un

我有一些对时间敏感的异步代码,只能通过记录实时数据然后查看日志来调试。因此,我用如下语句插入代码:

DBG(`Setting ${name} timer for ${amount} ms from runMore(${reason})`);
let debugOn = process.env["DEBUG_RATE_LIMIT_MAP"] === "1";
let DBG;
if (debugOn) {
    DBG = function(...args) {
        args.unshift(time() + ": ");
        console.log(...args);
    }
} else {
    DBG = function() {};
}
其中DBG有如下实现:

DBG(`Setting ${name} timer for ${amount} ms from runMore(${reason})`);
let debugOn = process.env["DEBUG_RATE_LIMIT_MAP"] === "1";
let DBG;
if (debugOn) {
    DBG = function(...args) {
        args.unshift(time() + ": ");
        console.log(...args);
    }
} else {
    DBG = function() {};
}
一般的想法是,如果设置了环境变量,它只输出到控制台

这一切都很好,但让我感到困扰的是,即使在未设置环境变量时它不会输出到控制台,它仍然会计算所有调试语句的参数,例如:

DBG(`Setting ${name} timer for ${amount} ms from runMore(${reason})`);
因此,它仍然在对每个语句进行一次性工作,以评估模板字符串。显然,JavaScript不是一种预处理语言,比如C++,可以编译调试代码。Javascript中有哪些技术可以在将来需要调试时将调试代码留在代码库中,但在不使用调试时不会降低运行时性能

对于任何其他代码参考,整个模块都在这里:。

是否需要DBG始终作为一个函数?如果没有,您可以执行以下操作:

let debugOn = process.env["DEBUG_RATE_LIMIT_MAP"] === "1";
let DBG;
if (debugOn) {
    DBG = function(...args) {
        args.unshift(time() + ": ");
        console.log(...args);
    }
}
然后在代码中,检查DBG是否是函数,而不是直接调用DBG:

if (typeof DBG === "function") {
    DBG(`Setting ${name} timer for ${amount} ms from runMore(${reason})`);
}

这样,您确实会有if条件检查的开销,但可以避免在生产环境中执行字符串文字。

根据一些评论,我目前的最佳想法是:

// environment variable that turns debug tracing on
let debugOn = process.env["DEBUG_RATE_MAP"] === "1";

function DBG(...args) {
    if (debugOn) {
        args.unshift(time() + ": ");
        console.log(...args);
    }
}
然后,在执行此操作的代码中:

if (debugOn) DBG(`Setting ${name} timer for ${amount} ms from runMore(${reason})`);
而且,如果它只是一个简单的字符串文字,因此不需要避免模板计算,我可以这样做:

DBG('All done.');

如果您使用任何类型的构建链,JS与任何预处理语言一样好——它只是编译成不同的JS。有transpiler插件可以从代码中删除调试语句。@Bergi-当前未使用生成链。另外,不要真的想删除代码,因为这样你就必须得到一个调试版本才能进行调试。所以,也许我的C++类比是一个坏的,因为这不是我真正想要的。我希望有一些运行时方案,实时成本更低。啊,好的。为此,我唯一能想到的就是使用带标记的模板文本,这样可以避免字符串连接。虽然不能确定它的开销,但您需要对其进行基准测试。@Bergi-我从来没有真正了解标记文字的常用用法。也许这是一种可能性,尽管在调用标记函数之前仍然解析模板文本,但它还没有生成完整的输出。是的,这会阻止额外的模板求值,但是在代码中到处散布是一种痛苦。我希望有更干净的东西。在这个特定的例子中,我可以使用if-debugOn…如果你使用typescript,你可以使用DBG?.stringLiteral,这样会更干净。最新的ES也会有:DBG会吗?如果DBG没有定义,templateLiteral会避免评估templateLiteral吗?这听起来可能很有趣,应该是。正如doc提到的,它将在DBG本身短路。它相当于DBG&&DBGtemplateLiteralIt很好,但是if条件在可读性方面更好,除非您将返回值赋给某个变量。另一件事:将其设为const debugOn=…。这样,优化编译器就可以推断假值不会改变,并且可以完全删除if块。@Bergi-我有意识地选择使用let,以便在调试时根据需要以编程方式更改该值。不过,了解优化是件好事。