希望您在挑戰 4中玩得開心。將來,如果您對某件事有什麼想法,可以作為一個好的挑戰,請告訴我。我一直在尋找好的材料!
恭喜, @landon !在 100 對 1,000 位數字(9.88 秒)和最長數字(7,150)挑戰中,您都擁有最快的(非工作人員)參賽成績。它不僅是唯一能夠在 10 秒內讀取所有 100 對 1,000 位數字的腳本(下一個最接近的只能讀取 10 對),而且還可以將兩個比下一個最接近的條目大 3.5 倍的數字相乘!此外,它是所有劇本(工作人員和非工作人員)中最短的,只有 1,000 多個字元。我已將其包含在下面的腳本中。四次挑戰後的總分為:
在我們討論大數相乘之前,讓我們先討論一下如何解包或向量化一串數字——將一串數字轉換成數字向量。正如我們上個月看到的那樣,使用子字串循環逐一解析一串數字的速度非常慢。這給我們留下了兩個一般的選擇:1)將字串解構為單獨的單元,然後將它們重新組合成可以轉換為向量的形式(例如,使用解析 )或 2)使用模式匹配。我最初傾向於使用方法 1。付出的努力太大,資訊和範例太少,而且我太懶了。我認為我已經用正規表示式函數滿足了我的所有需求,這是我非常熟悉的東西。不再。
這些挑戰讓我認識到模式匹配的速度和效率。正如負責這些功能的開發人員和挑戰的常客@Craige_Hales向我解釋的那樣,JSL 中的模式匹配例程是構建正規表示式的基礎。為了證明它們的效率,運行向量化範例.JSL中的程式碼,比較了四種不同的向量化方法。我還在腳本中添加了一個簡短的函數來產生一長串隨機數。對於包含 10,000 個數字的字串,循環中一次解析一個數字是迄今為止最慢的,在我的計算機上大約需要 11 秒。使用單字和連接清單將數字解構並重構為可以解析為向量的字串,效果更好(0.0965 秒)。
使用正則表達式和解析做同樣的事情比那個稍微好一點(0.08543)。模式匹配將這個時間減少了驚人的 4 倍 (0.02179)!雖然對於 50,000 位數字來說,時間差異很小,但如果我們考慮 5,000,000 位數字,兩種解析方法都需要大約 10 分鐘,而模式匹配則需要 2 秒,與其他方法不同,它幾乎呈線性增長!如果您想了解有關 JSL 中的模式匹配的更多信息,請查看@Craige_Hales或@David_Burnham編寫的腳本(他有幾篇自己的博客文章,其中包含更多信息和示例。)
繼續進行乘法運算。所有向量化均採用模式匹配。此外,第一個範例中使用了上次挑戰中最快的加法演算法。第一種方法( multiplyBig Slow.JSL )並沒有使用我們迄今為止在挑戰中所學到的知識。它每次將兩位數字相乘,確保根據被乘數和乘數的位置添加零(例如,當百位數字乘以十位數字時添加五個零)。儘管函數對輸入進行排序,使得第一個輸入較大,但這沒有任何好處。執行相同數量的操作。但這在最後的例子中將會改變。函數很慢,需要近 30 秒才能處理一組 100 個 100 位數字。
在倍增更快.JSL中,暫存器的數字位數從 1 位元增加到 7 位,大約是 JSL 在沒有溢位的情況下可以表示的數字的一半。當我們將兩個大的七位數字相乘時,這種選擇的原因就顯而易見了,其結果可能多達十四位數字。由於七位元暫存器可能包含 14 位數字,所以必須改變上一個範例中使用的加法例程,以便將第 7 位數字之後的任何數字送入下一個暫存器。儘管如此,由於只需要考慮正數,因此最終的程式碼要短得多。此外,將 100 個 100 位數字對相乘(0.04375 秒)的結果也得到了顯著改善。此實現也能合理地完成 100 個 1000 位元數字對的乘法(1.54 秒)。
只需一個簡單的改變,您就可以走得更快。 multiplyBig Fastest.JSL不是每次乘以一個暫存器,而是使用 JSL 矩陣運算將較短數字中的每個暫存器與較大數字的整個數相乘。這種方法比以前的方法更快,處理 100 個 1,000 位數字對只需 0.3015 秒,速度提高了 5 倍。
而且你還可以走得更快。檔案multiplyBig – Brady.JSL在計算 1,000 位數字的乘法時速度稍慢,但當數字達到約 2,000 位及以上時,速度更佳。這是透過改變運算順序來實現的,以便乘法和加法可以在同一個循環中完成。這背後的細節超出了我的興趣,但@brady_brady告訴我,如果有興趣的話,他很樂意寫一篇簡短的文章,我可以將其添加到這篇文章中。快點?或許。密碼學中通常使用兩種值得注意的乘法演算法,它們將乘法運算的次數從 O(n 2 ) 減少到O(n 1.58 )或更低。因為它們需要對大數字進行更多的加法運算,所以很難說它們在 JSL 中是否會更快。截至本文發表時,我已嘗試但無法實現這兩種演算法的快速 JSL 版本。
2020 年 8 月 1 日:感謝@Craige_Hales發現multiplyBig Fastest.JSL中的錯誤。我已糾正了這個問題。我還添加了 Craige 的 multiplyBig 腳本,我本來打算這麼做但忘記了。他使用查找表來加速演算法(但有一些注意事項)。像往常一樣,他的劇本經過了徹底的評論。