易語言效率與C++究竟差多少(質(zhì)數(shù)和)
易語言作為款主打 中文 易用 編程的開發(fā)軟件。但是很多人都在批評(píng)易語言的效率。
我們今天通過 質(zhì)數(shù)和計(jì)算 來看看易語言的效率到底與C++差了多少。
話不多說,這是今天的測試平臺(tái)
C++部分
開發(fā)環(huán)境VC++ 2019
Release x86
代碼優(yōu)化為 /O2
C++代碼(原本V2IDX是內(nèi)聯(lián)的,但是易語言不支持,為了達(dá)到一樣的效果,我取消了)
其余微小差異均已忽略
代碼源自知乎大神@wjhbb
原帖:https://www.zhihu.com/question/29580448
#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("請(qǐng)輸入您要求的質(zhì)數(shù)和的上限:" );
? ? LINT N ;
? ? cin >> N;
? ? int t = GetTickCount();
? ? printf("%lld\n", primesum(N));
? ? printf("耗時(shí)(ms)%u", GetTickCount() - t);
? ? cin >> N;
}
易語言部分
開發(fā)環(huán)境 易語言5.9
分別比較?動(dòng)態(tài)編譯?靜態(tài)編譯(VC98Linker)??黑月編譯(VC14.23Linker,C/C++方式編譯)
開啟快速數(shù)組訪問,不插入花指令,不打亂編譯結(jié)果.
代碼
.版本 2
.程序集 Main
.子程序 _啟動(dòng)子程序, 整數(shù)型, , 本子程序在程序啟動(dòng)后最先執(zhí)行
.局部變量 N, 長整數(shù)型
.局部變量 t, 整數(shù)型
標(biāo)準(zhǔn)輸出 (, “請(qǐng)輸入您要求的質(zhì)數(shù)和的上限:”)
N = 到長整數(shù) (標(biāo)準(zhǔn)輸入 ())
t = GetTickCount ()
標(biāo)準(zhǔn)輸出 (, 到文本 (Primesum (N)) + #換行符)
標(biāo)準(zhǔn)輸出 (, “耗時(shí)(ms)” + 到文本 (GetTickCount () - t))
標(biāo)準(zhǔn)輸入 ()
返回 (0)? ' 可以根據(jù)您的需要返回任意數(shù)值
.子程序 V2IDX, 長整數(shù)型
.參數(shù) V, 長整數(shù)型
.參數(shù) N, 長整數(shù)型
.參數(shù) Ndr, 長整數(shù)型
.參數(shù) nv, 長整數(shù)型
.如果真 (V ≥ Ndr)
? ? 返回 (N ÷ V - 1)
.如果真結(jié)束
返回 (nv - V)
.版本 2
.子程序 Primesum, 長整數(shù)型
.參數(shù) N, 長整數(shù)型
.局部變量 S, 長整數(shù)型, , "0"
.局部變量 V, 長整數(shù)型, , "0"
.局部變量 r, 長整數(shù)型
.局部變量 Ndr, 長整數(shù)型
.局部變量 nv, 長整數(shù)型
.局部變量 i, 長整數(shù)型
.局部變量 p, 長整數(shù)型
.局部變量 sp, 長整數(shù)型
.局部變量 p2, 長整數(shù)型
r = 求平方根 (N)
Ndr = N ÷ r
nv = r + Ndr - 1
重定義數(shù)組 (V, 假, nv)
重定義數(shù)組 (S, 假, nv)
i = 0
.判斷循環(huán)首 (i < r)
? ? V [i + 1] = N ÷ (i + 1)
? ? i = i + 1
.判斷循環(huán)尾 ()
i = r
.判斷循環(huán)首 (i < nv)
? ? V [i + 1] = V [i] - 1
? ? i = i + 1
.判斷循環(huán)尾 ()
i = 0
.判斷循環(huán)首 (i < nv)
? ? S [i + 1] = V [i + 1] × (V [i + 1] + 1) ÷ 2 - 1
? ? i = i + 1
.判斷循環(huán)尾 ()
p = 2
.判斷循環(huán)首 (p ≤ r)
? ? .如果真 (S [nv - p + 1] > S [nv - p + 2])
? ? ? ? sp = S [nv - p + 2]
? ? ? ? p2 = p × p
? ? ? ? i = 0
? ? ? ? .判斷循環(huán)首 (i < nv)
? ? ? ? ? ? .如果 (V [i + 1] ≥ p2)
? ? ? ? ? ? ? ? S [i + 1] = S [i + 1] - p × (S [V2IDX (V [i + 1] ÷ p, N, Ndr, nv) + 1] - sp)
? ? ? ? ? ? .否則
? ? ? ? ? ? ? ? 跳出循環(huán) ()
? ? ? ? ? ? .如果結(jié)束
? ? ? ? ? ? i = i + 1
? ? ? ? .判斷循環(huán)尾 ()
? ? .如果真結(jié)束
? ? p = p + 1
.判斷循環(huán)尾 ()
返回 (S [1])
?
UP翻譯的代碼不是很好,歡迎大家指正.
PS:GetTickCount()得到的時(shí)間差可能不會(huì)很準(zhǔn).,同時(shí)我也承認(rèn)這樣比較方法的不嚴(yán)謹(jǐn)性,所以測試結(jié)果僅供參考.
順帶提一下電腦CPU是i7-7700k
編譯生成后

先從一億以內(nèi)的質(zhì)數(shù)開始

當(dāng)我們提高計(jì)算量時(shí),我們會(huì)驚人的發(fā)現(xiàn) 易語言程序算錯(cuò)了
例如知乎上的10億

UP嘗試發(fā)現(xiàn)原因,覺得可能是一下幾點(diǎn)
1,UP技術(shù)太垃圾翻譯錯(cuò)了
2,UP主的盜版易語言的暗裝沒清干凈
3,易語言的數(shù)組只支持到INT的成員數(shù)
4,易語言的數(shù)值轉(zhuǎn)換問題
請(qǐng)大神們看看是什么情況.UP也不好妄下定論。
但是起碼證明了一點(diǎn),沒有不好的編程語言,只有效率低下的算法,在1億以內(nèi)易語言還是有準(zhǔn)確性的.如果其他編程語言用的算法比易語言低效,那也不見的比易語言快的.(UP用的算法也不一定是最快的算法).易語言作為一個(gè)怡情使用的開發(fā)軟件還是很不錯(cuò)的.
聽說易語言創(chuàng)始人吳濤將要為他的火山開發(fā)平臺(tái)添加PC端的開發(fā)功能,讓我們拭目以待.(UP在考慮要不要要火山上補(bǔ)個(gè)票)