希望您玩得开心挑战4 。 将来,如果您有什么想法可以成为一个很好的挑战,请告诉我。 我一直在寻找好的材料!
恭喜, @落在!您在 100 对 1,000 位数字(9.88 秒)和最长数字(7,150)挑战中都取得了最快的(非工作人员)参赛成绩。 它不仅是唯一能够在 10 秒内读取全部 100 对 1,000 位数字的脚本(下一个最接近的只能读取 10 个),而且它还可以将两个数字相乘,比下一个最接近的条目大 3.5 倍! 此外,它是所有剧本(职员和非职员)中最短的,只有 1,000 多个字符。 我已将其包含在下面的脚本中。 四次挑战后的总得分为:
在讨论大数相乘之前,我们先讨论一下对数字字符串进行解包或向量化——将数字字符串转换为数字向量。 正如我们上个月所看到的,使用一次一个来解析一串数字子字符串在一个循环中是非常慢的。 这给我们留下了两个一般选择:1)将字符串解构为单独的单元,然后将它们重新组合成可以转换为向量的形式(使用解析,例如)或,2)使用模式匹配。 我最初的倾向是使用方法 1。 多年来,我一直拒绝学习 JSL 模式匹配函数。 工作量太大,信息和例子太少,而且我太懒了。 我想我已经拥有了我所需要的一切正则表达式功能,我非常了解的东西。 不再。
这些挑战让我对模式匹配的速度和效率大开眼界。 正如向我解释的@Craige_Hales ,负责这些功能的开发人员和挑战的定期参与者,JSL 中的模式匹配例程是其基础正则表达式建成。 为了展示其效率,请运行以下代码矢量化示例.JSL ,比较了四种不同的矢量化方法。 我还在脚本中包含了一个简短的函数来生成一长串随机数。 对于一串 10,000 个数字,在循环中一次解析一个数字是迄今为止最慢的,在我的机器上大约需要 11 秒。 使用字和串联列表将数字解构并重建为可以解析为向量的字符串是世界上最好的(0.0965秒)。
使用做同样的事情正则表达式和解析比 (0.08543) 稍好一些。 模式匹配将时间缩短了惊人的 4 倍 (0.02179)! 虽然时间差异对于 50,000 位数字而言很小,但如果我们考虑 5,000,000 位数字,两种解析方法都需要大约 10 分钟,而模式匹配需要 2 秒,与其他方法不同,几乎呈线性扩展! 如果您想了解有关 JSL 中模式匹配的更多信息,请查看由@Craige_Hales或者@大卫_伯纳姆(谁有他自己的一些博客文章包含更多信息和示例.)
继续进行乘法例程。 模式匹配用于所有矢量化。 此外,第一个示例中使用了上次挑战中最快的加法算法。 第一种方法(乘法大慢.JSL )除了我们迄今为止在挑战中学到的知识之外,没有使用任何内容。 它一次将两个数字相乘,并确保根据被乘数和乘数的位置添加零(例如,当百位数字乘以十位数字时添加五个零)。 尽管函数对输入进行排序,因此第一个输入更大,但这没有任何好处。 执行相同数量的操作。 然而,这将在最后一个示例中发生变化。 该功能速度较慢,需要近 30 秒才能完成一组 100 个 100 位数字。
在乘法大更快.JSL寄存器中的位数从一位增加到七位,大约是 JSL 可以表示的位数的一半而不溢出。 当我们将两个大的七位数字相乘时,其结果可能高达十四位数字,这种选择的原因就很明显了。 由于 7 位寄存器可能包含 14 位数字,因此必须更改上一个示例中使用的加法例程,以便将第 7 位数字之外的任何内容传送到下一个寄存器。 尽管如此,由于只需要考虑正数,因此生成的代码要短得多。 此外,对于 100 100 位数字对的乘法,结果显着改善(0.04375 秒)。 此实现还可以合理地完成 100 个 1000 位数字对的乘法(1.54 秒)。
通过一项简单的更改,您可以走得更快。 而不是一次乘以一个寄存器,乘法大最快.JSL使用 JSL 矩阵运算将每个寄存器中较短的数字与整个较大的数字相乘。 这种方法比以前的方法更快,100 个 1,000 位数字对的计时时间为 0.3015 秒,提高了 5 倍。
而且你可以走得更快。 文件乘法大 – Brady.JSL虽然在 1,000 位数字相乘时速度稍慢,但当数字大小达到约 2,000 位数字及以上时,它的性能更佳。 这是通过改变运算顺序来实现的,以便可以在同一循环中完成乘法和加法。 这背后的细节超出了我的范围,但是@brady_brady告诉我他很乐意写一篇简短的文章,如果有兴趣的话我可以添加到这篇文章中。 快点? 或许。 密码学中通常使用两种著名的乘法算法,它们可以将乘法运算的数量从 O(n 2 ) 到在1.58 )或者降低。 因为它们需要更多的大数加法运算,所以很难说它们在 JSL 中是否会更快。 截至这篇文章,我尝试过,但无法实现这两种算法的快速 JSL 版本。
2020 年 8 月 1 日:谢谢@Craige_Hales用于捕获错误乘法大最快.JSL 。 我已经纠正了这个问题。 我还添加了Craige 的multiplyBig 脚本,我本来打算这样做但忘记了。 他使用查找表作为加速算法的一种方法(有一些注意事项)。 像往常一样,他的剧本是彻底的评论。