ChatGPT解决这个技术问题 Extra ChatGPT

将布尔结果转换为数字/整数

我有一个存储 falsetrue 的变量,但我分别需要 01。我怎样才能做到这一点?

下面是一些提供的技术的性能比较:jsperf.com/conversion-from-boolean-to-number
Node.JS 用户会希望使用 bool === true ? 1 : 0,因为它是迄今为止 V8 中最快的。
或者只是bool ? 1 : 0;

l
lonesomeday

使用 unary + operator,它将其操作数转换为数字。

+ true; // 1
+ false; // 0

当然,请注意,您仍然应该清理服务器端的数据,因为无论客户端代码怎么说,用户都可以将任何数据发送到您的服务器。


虽然很酷(我从来没有想过这个),但它是 incredibly slow(准确地说,在 Chrome 中慢了 97%)。警惕!
查看this revisionNumber() 甚至更慢。
bool === true ? 1 : 0 似乎是最快的,紧随 bool | 0 之后。
乘法(例如 3*false)感觉很不对,但它确实有效。 :) 谢谢!
@DerkJanSpeelman Typescript 中不允许的事实并不意味着您不应该在 Javascript 中执行此操作。它们是不同的(尽管相关的)语言。
A
Andy Rose

Javascript 有一个可以使用的三元运算符:

var i = result ? 1 : 0;

最佳答案。为什么?这适用于更普遍并接受任何类型(字符串、数字等)的真实性。一元答案确实很聪明,但如果我将字符串传递给它,它会返回 NaN。所以如果你想要L33T并保证输入,那就去urary,否则我认为三元+真值测试是最好的。
该解决方案基本上是使用三元运算符最小化 if 语句。
三元解法是最快的方法之一。 +trueNumber(true) 等其他解决方案非常慢。请参阅benchmark
@Dominik 该基准测试工具非常令人困惑和误导。 jsbench.me 是一个更好的选择。
k
kralyk

恕我直言,最好的解决方案是:

fooBar | 0

这在 asm.js 中用于强制整数类型。


最快的之一; +1。
好东西。您也可以使用“布尔 ^ 0”。 OR 或 XOR 有效。
如果 fooBar 不是,这不会返回 1 整数吗?
@ESR 它将所有内容都转换为一个数字,但并不总是您想要的数字,如果您正在处理其他真实类型。 1 | 0 = 1; 0 | 0 = 0; true | 0 = 1; false | 0 = 0; 'foo' | 0 = 0; undefined | 0 = 0
打字稿错误:The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
R
Roko C. Buljan

我更喜欢使用 Number function。它接受一个对象并将其转换为一个数字。

例子:

var myFalseBool = false;
var myTrueBool = true;

var myFalseInt = Number(myFalseBool);
console.log(myFalseInt === 0);

var myTrueInt = Number(myTrueBool);
console.log(myTrueInt === 1);

您可以在 jsFiddle 中对其进行测试。


这是迄今为止最好的答案。当然在底部。只有“它需要一个对象”是不对的。
链接到 mdn 比 w3schools(eeek !) 好得多:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
我认为这是最好的方式,因为它易于阅读和意图揭示。
它也是最慢的。
很好,这正是我会做的。而不是使用三元表达式。
P
Philip

键入的方法是:

Number(true) // 1
Number(false) // 0

终于有一个体面的答案了。谢谢。
三元解法是最快的方法之一。 +trueNumber(true) 等其他解决方案非常慢。请参阅benchmark
G
Gal Talmor

我创建了所有建议答案的 JSperf 比较。

TL;DR - 当前所有浏览器的最佳选择是:

val | 0;

.

更新:

现在看起来它们都非常相似,除了 Number() 函数是最慢的,而最好的是 val === true ? 1 : 0;


有趣的是,三进制现在在 macOS 10.13.3 上的 Chrome 64.0.3282 中是最快的。
这将是当时最快的选择。这与它是最佳选择不同。
t
tonyjcamp

我今天才发现这个快捷方式。

~~(真实)

~~(假)

人们比我能解释的聪明得多:

http://james.padolsey.com/javascript/double-bitwise-not/


有趣的。我今天学了些新东西。不过,我不会在任何项目中使用这种技术,因为它可能会混淆未来的我或队友。
hacky js 是我的最爱。认真的,+1
G
Gordon

当 JavaScript 需要一个数字值但接收到一个布尔值时,它会将该布尔值转换为一个数字:true 和 false 分别转换为 1 和 0。所以你可以利用这一点;

变量 t = 真;变量 f = 假;控制台.log(t*1); // t*1 === 1 console.log(f*1); // f*1 === 0 console.log(+t); // 0+t === 1 或缩短为 +t === 1 console.log(+f); //0+f === 0 或缩短为 +f === 0

进一步阅读 The Definitive Guide to Javascript 的类型转换第 3.8 章。


T
Teodor Maxim

TL;DR:避免使用 Number 构造函数和 +bool;默认情况下使用简单的 if;诉诸布尔| 0, 1 * bool 如果您的项目中的基准以这种方式做得更好。

这是一个相当古老的问题,并且存在许多有效的答案。我注意到这里的所有基准都是无关紧要的 - 没有一个考虑到 branch prediction。此外,如今,JS 引擎不只是解释代码,它们JIT compile 将其转换为本地机器代码并在执行之前对其进行优化。这意味着,除了分支预测之外,编译器甚至可以用它们的最终值替换表达式。

现在,这两个因素如何影响布尔到整数转换的性能?让我们来了解一下!在我们进入基准测试之前,了解我们的基准测试是很重要的。对于转换,我们使用以下七种转换方法:

数字构造函数:Number(bool)

If 语句(使用三元): bool ? 1 : 0

一元运算符 +: +bool

按位或:布尔 | 0

按位与:布尔 & 1

按位双非:~~bool

数字乘法:bool * 1

“转换”是指将 false 转换为 0 并将 true 转换为 11。每种转换方法运行 100000 次,测量操作/毫秒。在下表中,转换方法将相应地分组到它们的结果中。结果后面的百分比表示此方法与同一浏览器中最快的方法相比有多慢。如果没有百分比,则该方法要么是最快的,要么差异可以忽略不计(<0.01%)。基准测试在配备 Apple M1 Pro 10 核 CPU 和 16GB RAM 的 Macbook Pro 16 英寸机器上运行。浏览器是 Chrome 102、Firefox 101 和 Safari 15.5。

第一个 benchmark 转换常量 true

方法 Chrome (V8) Firefox (Spidermonkey) Safari (Webkit) Number(bool) 31745.89 392.35 - 91.48% 31231.79 bool ? 1 : 0 31592.8 - 0.48% 4602.64 27533.47 - 11.84% + 布尔值 31332.57 - 1.3% 4463.41 - 3.02% 27378.7 - 12.34% 布尔值 | 0 31488.5 - 0.81% 4441.4 - 3.5% 27222 - 12.84% bool & 1 31383.17 - 1.14% 4459.64 - 3.11% 27317.41 - 12.53% ~~bool 31265.85 - 1.51% 4442.35 - 3.48% 27434.72 - 12.16% bool * 1 31374.4 - 1.17% 4444.05 - 3.45% 27381.19 - 12.33%

有趣的! V8 显示了一些巨大的数字,所有数字都大致相同! Spidermonkey 并没有真正发光,但我们可以看到按位和乘法技巧排在第一位,三进制 if 排在第二位。最后,Webkit 的 Number 与 V8 类似,其他方法落后,但都彼此接近。有什么外卖?浏览器大多设法用简单的值 1 替换我们的转化。这种优化将发生在我们可以将布尔值替换为恒定值的地方。 Number 构造函数是一个有趣的异常 - 它在 Firefox 中严重落后(91% !),而在 Safari 中它是最快的!

以上不是我们在实际项目中会遇到的情况。所以让我们改变我们的变量:bool 现在是 Math.random() < 0.5。这产生 true 的 50% 的机会,false 的 50%。我们的结果会改变吗?让我们运行这个 benchmark 来看看。

方法 Chrome (V8) Firefox (Spidermonkey) Safari (Webkit) Number(bool) 1648.83 - 2.26% 280.34 - 86.4% 8014.69 bool ? 1 : 0 804.27 - 52.32% 731.57 - 64.5% 1294.02 - 83.85% + 布尔值 1670.79 - 0.95% 2057.94 7753.99 - 3.25% 布尔值 | 0 1668.22 - 1.11% 2054.17 7764.81 - 3.12% bool & 1 1675.52 - 0.67% 2056.76 7193.08 - 10.25% ~~bool 1676.24 - 0.63% 2056.18 7669.48 - 4.31% bool * 1 1686.88 2060.88 7751.48 - 3.28%

现在的结果更加一致。我们看到跨浏览器的三元 if、按位和乘法方法的数字相似,Number 构造函数再次在 Firefox 上执行最差。三元落在后面,因为它会生成分支。 Safari 似乎是我们总体上表现最好的,每种方法都产生了惊人的快速结果!

现在让我们看看分支预测如何通过以下 benchmark 影响我们的结果,我们将布尔变量更改为 Math.random() < 0.01,这意味着 1% true,99% false

方法 Chrome (V8) Firefox (Spidermonkey) Safari (Webkit) Number(bool) 1643.13 - 1.68% 280.06 - 86.4% 8071.65 bool ? 1 : 0 1590.55 - 4.83% 1970.66 - 4.32% 7119.59 - 11.8% + 布尔值 1662.09 - 0.55% 2054.09 7762.03 - 3.84% 布尔值 | 0 1669.35 2051.85 7743.95-4.06%布尔&1 1661.09-0.61%2057.62 7454.45-7.65%~~ bool 1662.94-0.5%2059.65 7739.4-4.12% - 4.12%BOOL * 1 1671.28 2048.87777787.38.38.38.38.38.87.87.887.887.88.88.88.88. bool。38.38.38.38.38.87.87.88.88.88.88.88. bool。38.38.38.38.38.87.88.88.88.88.88. bool。38.38.38.38.38.87.88.88.88.88.88. bool。

意外?预期的?我会说后者,因为在这种情况下,分支预测在几乎所有情况下都是成功的,因为三元 if 和按位黑客之间的差异较小。其他结果都是一样的,这里不多说。我仍然会指出 Firefox 中 Number 的可怕性能 - 为什么?

这一努力让我们回到了最初的问题:如何在 Javascript 中将 bool 转换为 int?以下是我的建议:

通常使用 if 语句。不要变得聪明——浏览器通常会做得更好,而且通常意味着大多数情况。它们是这里所有方法中最易读和最清晰的。当我们处于可读性时,也许使用 if (bool) 而不是那个丑陋的三元!我希望 Javascript 拥有 Rust 或 Python 所拥有的...

真正需要时使用其余部分。也许您项目中的基准测试执行不合标准,并且您发现令人讨厌的 if 会导致性能不佳 - 如果是这种情况,请随意进入无分支编程!但是不要在那个兔子洞里走得太深,相信我,没有人会从 -1 * (a < b) + 1 * (a > b) 之类的东西中受益。

还有一些细节:

避免数字(布尔)。虽然 Chromium 平台(Chrome + Edge)在全球拥有约 68% 的市场份额,Safari 为 19%,Firefox 仅为 3.6%,但仍有足够多的其他快速执行的方法不会完全牺牲一部分用户. Firefox 拥有 7% 的桌面市场份额,相当于 1.73 亿用户。

在较旧的基准测试中,+bool 的性能与 Firefox 中的 Number 相似,可能也要考虑到这一点 - 按位 hack 和乘法在所有情况下在所有浏览器中提供一致的性能结果。布尔 | 0 最有可能让其他开发人员熟悉。

我将永远感谢您阅读到最后——这是我第一个更长的、重要的 StackOverflow 答案,如果它有帮助和有见地,它对我来说意味着世界。如果您发现任何错误,请随时纠正我!

编辑:以前的基准测试工具提供了模糊的结果,没有衡量单位。我已经更改了它,还添加了 Safari 的基准,这影响了结论。

定义了转换,因为不清楚布尔到整数的含义。例如,Go 根本不支持这种转换。


赞成这项努力,但我想不出一个真正的用例,当这种操作的性能很重要时:)
@skwisgaar 完全同意,虽然我认为这个操作主要是在人们觉得需要优化的时候考虑使用的
优秀的帖子,但我试图弄清楚基准数字的解释,正如你所说的“操作/秒”。在我使用了 5 年的 Acer 笔记本电脑的 V8 浏览器调试器中,以下百万次操作在 36 毫秒(!)内运行:start=performance.now(); for (let i = 0; i < 1000000; i++) {let x = +(Math.random()<0.5);} end=performance.now(); console.log(end-start)。我在误解什么?
感谢您的回复!自己运行基准测试,数字看起来更像操作/_毫秒_。尽管在 Chrome 和 Firefox 的 DevTools 中,相同的基准测试似乎在我的机器上也运行得更快——也许 JSBench 是一个瓶颈。我现在将更改度量单位,但这必须进一步研究。
@TeodorMaxim 刚刚看到您已回复...听起来不清楚 JSBench 报告了什么...您最好创建自己的迷你基准测试工具,因为至少您会确切地知道正在测量的内容以及确切地知道如何解释结果。
x
xanatos

一元 + 运算符将处理此问题:

var test = true;
// +test === 1
test = false;
// +test === 0

您自然会希望在存储之前在服务器上对其进行完整性检查,因此无论如何这可能是一个更明智的地方。


我已将注释更改为 ===,因为即使没有“显式转换 :-) true === 1 也是假的,true == 1 也是假的。
N
Nicholas R. Grant

我只是在我正在编写的一些代码中处理这个问题。我的解决方案是使用按位和。

var j = bool & 1;

处理持续问题的更快方法是创建一个函数。其他人可读性更高,在维护阶段更易于理解,并消除了编写错误的可能性。

function toInt( val ) {
    return val & 1;
}

var j = toInt(bool);

编辑 - 2014 年 9 月 10 日

出于某种原因,在 Chrome 中使用与运算符相同的三元运算符进行的转换不会更快。对于为什么它更快没有意义,但我认为这是某种低级优化,在此过程中的某个地方是有意义的。

var j = boolValue === true ? 1 : 0;

自己测试:http://jsperf.com/boolean-int-conversion/2

在 FireFox 和 Internet Explorer 中,使用我发布的版本通常更快。

编辑 - 2017 年 7 月 14 日

好的,我不会告诉你应该或不应该使用哪一个。每个该死的浏览器在使用每种方法执行操作的速度上一直在上下波动。 Chrome 在某一时刻实际上让按位 & 版本比其他版本做得更好,但后来突然变得更糟了。我不知道他们在做什么,所以我将把它留给谁在乎。很少有理由关心这样的操作完成得有多快。即使在移动设备上,它也是一项无操作。

另外,这里有一个更新的方法来添加一个不能被覆盖的“toInt”原型。

Object.defineProperty(Boolean.prototype, "toInt", { value: function()
{
    return this & 1;
}});

我对这篇文章投了两次反对票。你为什么不解释你为什么拒绝它。否则,这只是没有正当理由的反对票。
jsperf 的 99 倍结果只会让你走上过早的优化路径,当你应该专注于那个丑陋的 SQL 语句时,优化了几纳秒的循环。感谢您提供几种不同的方法来解决这个问题
什么SQL语句?这里没有一个查询。如果您指的是 JSPerf,我是从其他人的测试中链接的。这不是我自己的。老实说,我不关心这个的性能方面,因为它是一个无操作。我创建了自己的语言,它的功能几乎与 JS 相同,我记得强制转换为 int 是一个愚蠢的快速操作。攀登原型链不是。这就是为什么我仍然推荐我这样做的第一种方法,它具有一个可以由编译器内联的简单函数。
SQL 的东西是一个概括。感谢您的洞察力
R
REMqb

您还可以添加 0,使用移位运算符或异或:

val + 0;
val ^ 0;
val >> 0;
val >>> 0;
val << 0;

这些具有与其他答案相似的速度。


J
Jose Velasco

在我的上下文中,我从布尔值获取不透明度值的 React Native,最简单的方法是:使用一元 + 运算符。

+ true; // 1
+ false; // 0

这会将布尔值转换为数字;

style={ opacity: +!isFirstStep() }

s
silkfire

+!! 允许您将其应用于变量,即使它是 undefined

+!!undefined    // 0
+!!false        // 0
+!!true         // 1

+!!(<boolean expression>)  // 1 if it evaluates to true, 0 otherwise

D
DroidOS

您可以通过简单地扩展布尔原型来做到这一点

Boolean.prototype.intval = function(){return ~~this}

理解那里发生的事情并不容易,所以一个替代版本将是

Boolean.prototype.intval = function(){return (this == true)?1:0}

完成了你可以做的事情

document.write(true.intval());

当我使用布尔值来存储条件时,我经常将它们转换为位域,在这种情况下,我最终会使用原型函数的扩展版本

Boolean.prototype.intval = function(places)
{
 places = ('undefined' == typeof(places))?0:places; 
 return (~~this) << places
}

你可以用它做

document.write(true.intval(2))

它产生 4 作为其输出。


E
Esger
let integerVariable = booleanVariable * 1;

K
Kamil Kiełczewski

尝试

val*1

让 t=true;让 f=false;控制台.log(t*1);控制台.log(f*1)


D
DarckBlezzer

我已经测试了所有这些示例,我做了一个基准测试,最后我建议您选择较短的,它不会影响性能。

在 Ubuntu 服务器 14.04、nodejs v8.12.0 - 26/10/18 中运行

    let i = 0;
console.time("TRUE test1")
    i=0;
    for(;i<100000000;i=i+1){
        true ? 1 : 0;
    }
console.timeEnd("TRUE test1")


console.time("FALSE test2")
    i=0;
    for(;i<100000000;i=i+1){
        false ? 1 : 0;
    }
console.timeEnd("FALSE test2")

console.log("----------------------------")

console.time("TRUE test1.1")
    i=0;
    for(;i<100000000;i=i+1){
        true === true ? 1 : 0;
    }
console.timeEnd("TRUE test1.1")


console.time("FALSE test2.1")
    i=0;
    for(;i<100000000;i=i+1){
        false === true ? 1 : 0;
    }
console.timeEnd("FALSE test2.1")

console.log("----------------------------")

console.time("TRUE test3")
    i=0;
    for(;i<100000000;i=i+1){
        true | 0;
    }
console.timeEnd("TRUE test3")

console.time("FALSE test4")
    i=0;
    for(;i<100000000;i=i+1){
        false | 0;
    }
console.timeEnd("FALSE test4")

console.log("----------------------------")

console.time("TRUE test5")
    i=0;
    for(;i<100000000;i=i+1){
        true * 1;
    }
console.timeEnd("TRUE test5")

console.time("FALSE test6")
    i=0;
    for(;i<100000000;i=i+1){
        false * 1;
    }
console.timeEnd("FALSE test6")

console.log("----------------------------")

console.time("TRUE test7")
    i=0;
    for(;i<100000000;i=i+1){
        true & 1;
    }
console.timeEnd("TRUE test7")

console.time("FALSE test8")
    i=0;
    for(;i<100000000;i=i+1){
        false & 1;
    }
console.timeEnd("FALSE test8")

console.log("----------------------------")

console.time("TRUE test9")
    i=0;
    for(;i<100000000;i=i+1){
        +true;
    }
console.timeEnd("TRUE test9")

console.time("FALSE test10")
    i=0;
    for(;i<100000000;i=i+1){
        +false;
    }
console.timeEnd("FALSE test10")

console.log("----------------------------")

console.time("TRUE test9.1")
    i=0;
    for(;i<100000000;i=i+1){
        0+true;
    }
console.timeEnd("TRUE test9.1")

console.time("FALSE test10.1")
    i=0;
    for(;i<100000000;i=i+1){
        0+false;
    }
console.timeEnd("FALSE test10.1")

console.log("----------------------------")

console.time("TRUE test9.2")
    i=0;
    for(;i<100000000;i=i+1){
        -true*-1;
    }
console.timeEnd("TRUE test9.2")

console.time("FALSE test10.2")
    i=0;
    for(;i<100000000;i=i+1){
        -false*-1;
    }
console.timeEnd("FALSE test10.2")

console.log("----------------------------")

console.time("TRUE test9.3")
    i=0;
    for(;i<100000000;i=i+1){
        true-0;
    }
console.timeEnd("TRUE test9.3")

console.time("FALSE test10.3")
    i=0;
    for(;i<100000000;i=i+1){
        false-0;
    }
console.timeEnd("FALSE test10.3")

console.log("----------------------------")

console.time("TRUE test11")
    i=0;
    for(;i<100000000;i=i+1){
        Number(true);
    }
console.timeEnd("TRUE test11")

console.time("FALSE test12")
    i=0;
    for(;i<100000000;i=i+1){
        Number(false);
    }
console.timeEnd("FALSE test12")

console.log("----------------------------")

console.time("TRUE test13")
    i=0;
    for(;i<100000000;i=i+1){
        true + 0;
    }
console.timeEnd("TRUE test13")

console.time("FALSE test14")
    i=0;
    for(;i<100000000;i=i+1){
        false + 0;
    }
console.timeEnd("FALSE test14")

console.log("----------------------------")

console.time("TRUE test15")
    i=0;
    for(;i<100000000;i=i+1){
        true ^ 0;
    }
console.timeEnd("TRUE test15")

console.time("FALSE test16")
    i=0;
    for(;i<100000000;i=i+1){
        false ^ 0;
    }
console.timeEnd("FALSE test16")

console.log("----------------------------")

console.time("TRUE test17")
    i=0;
    for(;i<100000000;i=i+1){
        true ^ 0;
    }
console.timeEnd("TRUE test17")

console.time("FALSE test18")
    i=0;
    for(;i<100000000;i=i+1){
        false ^ 0;
    }
console.timeEnd("FALSE test18")

console.log("----------------------------")

console.time("TRUE test19")
    i=0;
    for(;i<100000000;i=i+1){
        true >> 0;
    }
console.timeEnd("TRUE test19")

console.time("FALSE test20")
    i=0;
    for(;i<100000000;i=i+1){
        false >> 0;
    }
console.timeEnd("FALSE test20")

console.log("----------------------------")

console.time("TRUE test21")
    i=0;
    for(;i<100000000;i=i+1){
        true >>> 0;
    }
console.timeEnd("TRUE test21")

console.time("FALSE test22")
    i=0;
    for(;i<100000000;i=i+1){
        false >>> 0;
    }
console.timeEnd("FALSE test22")

console.log("----------------------------")

console.time("TRUE test23")
    i=0;
    for(;i<100000000;i=i+1){
        true << 0;
    }
console.timeEnd("TRUE test23")

console.time("FALSE test24")
    i=0;
    for(;i<100000000;i=i+1){
        false << 0;
    }
console.timeEnd("FALSE test24")

console.log("----------------------------")

console.time("TRUE test25")
    i=0;
    for(;i<100000000;i=i+1){
        ~~true;
    }
console.timeEnd("TRUE test25")

console.time("FALSE test26")
    i=0;
    for(;i<100000000;i=i+1){
        ~~false;
    }
console.timeEnd("FALSE test26")

console.log("----------------------------")

console.time("TRUE test25.1")
    i=0;
    for(;i<100000000;i=i+1){
        ~true*-1-1;
    }
console.timeEnd("TRUE test25.1")

console.time("FALSE test26.1")
    i=0;
    for(;i<100000000;i=i+1){
        ~false*-1-1;
    }
console.timeEnd("FALSE test26.1")

console.log("----------------------------")

console.time("TRUE test27")
    i=0;
    for(;i<100000000;i=i+1){
        true/1;
    }
console.timeEnd("TRUE test27")

console.time("FALSE test28")
    i=0;
    for(;i<100000000;i=i+1){
        false/1;
    }
console.timeEnd("FALSE test28")

结果

TRUE test1: 93.301ms
FALSE test2: 102.854ms
----------------------------
TRUE test1.1: 118.979ms
FALSE test2.1: 119.061ms
----------------------------
TRUE test3: 97.265ms
FALSE test4: 108.389ms
----------------------------
TRUE test5: 85.854ms
FALSE test6: 87.449ms
----------------------------
TRUE test7: 83.126ms
FALSE test8: 84.992ms
----------------------------
TRUE test9: 99.683ms
FALSE test10: 87.080ms
----------------------------
TRUE test9.1: 85.587ms
FALSE test10.1: 86.050ms
----------------------------
TRUE test9.2: 85.883ms
FALSE test10.2: 89.066ms
----------------------------
TRUE test9.3: 86.722ms
FALSE test10.3: 85.187ms
----------------------------
TRUE test11: 86.245ms
FALSE test12: 85.808ms
----------------------------
TRUE test13: 84.192ms
FALSE test14: 84.173ms
----------------------------
TRUE test15: 81.575ms
FALSE test16: 81.699ms
----------------------------
TRUE test17: 81.979ms
FALSE test18: 81.599ms
----------------------------
TRUE test19: 81.578ms
FALSE test20: 81.452ms
----------------------------
TRUE test21: 115.886ms
FALSE test22: 88.935ms
----------------------------
TRUE test23: 82.077ms
FALSE test24: 81.822ms
----------------------------
TRUE test25: 81.904ms
FALSE test26: 82.371ms
----------------------------
TRUE test25.1: 82.319ms
FALSE test26.1: 96.648ms
----------------------------
TRUE test27: 89.943ms
FALSE test28: 83.646ms