易語言作為款主打 中文 易用 程式設計的開發軟體。但是很多人都在批評易語言的效率。
我們今天通過 質數和計算 來看看易語言的效率到底與C++差了多少。
話不多說,這是今天的測試平臺
- C++部分
- 開發環境VC++ 2019
- Release x86
- 程式碼優化為 /O2
C++程式碼(原本V2IDX是內聯的,但是易語言不支援,為了達到一樣的效果,我取消了)
其餘微小差異均已忽略
程式碼源自知乎大神@wjhbb
原帖
#include <math.h>
#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <windows.h>
#define LINT long long
LINT V2IDX(LINT v, LINT N, LINT Ndr, LINT nv) {
return v >= Ndr ? (N / v - 1) : (nv - v);
}
LINT primesum(LINT N) {
LINT* S;
LINT* V;
LINT r = (LINT)sqrt(N);
LINT Ndr = N / r;
assert(r * r <= N and (r + 1) * (r + 1) > N);
LINT nv = r + Ndr - 1;
V = new LINT[nv];
S = new LINT[nv];
for (LINT i = 0; i < r; i++) {
V[i] = N / (i + 1);
}
for (LINT i = r; i < nv; i++) {
V[i] = V[i - 1] - 1;
}
for (LINT i = 0; i < nv; i++) {
S[i] = V[i] * (V[i] + 1) / 2 - 1;
}
for (LINT p = 2; p <= r; p++) {
if (S[nv - p] > S[nv - p + 1]) {
LINT sp = S[nv - p + 1];
LINT p2 = p * p;
for (LINT i = 0; i < nv; i++) {
if (V[i] >= p2) {
S[i] -= p * (S[V2IDX(V[i] / p, N, Ndr, nv)] - sp);
}
else {
break;
}
}
}
}
return S[0];
}
int main() {
using std::cin;
printf("請輸入您要求的質數和的上限:" );
LINT N ;
cin >> N;
int t = GetTickCount();
printf("%lld\n", primesum(N));
printf("耗時(ms)%u", GetTickCount() - t);
cin >> N;
}
易語言部分
- 開發環境 易語言5.9
- 分別比較 動態編譯 靜態編譯(VC98Linker) 黑月編譯(VC14.23Linker,C/C++方式編譯)
- 開啟快速陣列訪問,不插入花指令,不打亂編譯結果.
.版本 2
.程式集 Main
.子程式 _啟動子程式, 整數型, , 本子程式在程式啟動後最先執行
.區域性變數 N, 長整數型
.區域性變數 t, 整數型
標準輸出 (, “請輸入您要求的質數和的上限:”)
N = 到長整數 (標準輸入 ())
t = GetTickCount ()
標準輸出 (, 到文字 (Primesum (N)) + #換行符)
標準輸出 (, “耗時(ms)” + 到文字 (GetTickCount () - t))
標準輸入 ()
返回 (0) ' 可以根據您的需要返回任意數值
.子程式 V2IDX, 長整數型
.引數 V, 長整數型
.引數 N, 長整數型
.引數 Ndr, 長整數型
.引數 nv, 長整數型
.如果真 (V ≥ Ndr)
返回 (N ÷ V - 1)
.如果真結束
返回 (nv - V)
.版本 2
.子程式 Primesum, 長整數型
.引數 N, 長整數型
.區域性變數 S, 長整數型, , "0"
.區域性變數 V, 長整數型, , "0"
.區域性變數 r, 長整數型
.區域性變數 Ndr, 長整數型
.區域性變數 nv, 長整數型
.區域性變數 i, 長整數型
.區域性變數 p, 長整數型
.區域性變數 sp, 長整數型
.區域性變數 p2, 長整數型
r = 求平方根 (N)
Ndr = N ÷ r
nv = r + Ndr - 1
重定義陣列 (V, 假, nv)
重定義陣列 (S, 假, nv)
i = 0
.判斷迴圈首 (i < r)
V [i + 1] = N ÷ (i + 1)
i = i + 1
.判斷迴圈尾 ()
i = r
.判斷迴圈首 (i < nv)
V [i + 1] = V [i] - 1
i = i + 1
.判斷迴圈尾 ()
i = 0
.判斷迴圈首 (i < nv)
S [i + 1] = V [i + 1] × (V [i + 1] + 1) ÷ 2 - 1
i = i + 1
.判斷迴圈尾 ()
p = 2
.判斷迴圈首 (p ≤ r)
.如果真 (S [nv - p + 1] > S [nv - p + 2])
sp = S [nv - p + 2]
p2 = p × p
i = 0
.判斷迴圈首 (i < nv)
.如果 (V [i + 1] ≥ p2)
S [i + 1] = S [i + 1] - p × (S [V2IDX (V [i + 1] ÷ p, N, Ndr, nv) + 1] - sp)
.否則
跳出迴圈 ()
.如果結束
i = i + 1
.判斷迴圈尾 ()
.如果真結束
p = p + 1
.判斷迴圈尾 ()
返回 (S [1])
UP翻譯的程式碼不是很好,歡迎大家指正.
PS:GetTickCount()得到的時間差可能不會很準.,同時我也承認這樣比較方法的不嚴謹性,所以測試結果僅供參考.
順帶提一下電腦CPU是i7-7700k
編譯生成後
可以發現C++的體積是最小的(易語言動態編譯的還要帶幾個支援庫檔案)
先從一億以內的質數開始
可以發現他們之間的速度差距
當我們提高計算量時,我們會驚人的發現 易語言程式算錯了
例如知乎上的10億
UP嘗試發現原因,覺得可能是一下幾點
- UP技術太垃圾翻譯了
- UP主的盜版易語言的暗裝沒清乾淨
- 易語言的陣列只支援到INT的成員數
- 易語言的數值轉換問題
請大神們看看是什麼情況.UP也不好妄下定論。
但是起碼證明了一點,沒有不好的程式語言,只有效率低下的演算法,在1億以內易語言還是有準確性的.如果其他程式語言用的演算法比易語言低效,那也不見的比易語言快的.(UP用的演算法也不一定是最快的演算法).易語言作為一個怡情使用的開發軟體還是很不錯的.
聽說易語言創始人吳濤將要為他的火山開發平臺新增PC端的開發功能,讓我們拭目以待.(UP在考慮要不要要火山上補個票)