《程式設計珠璣》程式碼之路14:兩個不會演算法也能把效率提升4倍的小套路
現在我們假設要在沒排序的陣列中找一個數:
菜狗也能寫出如下的演算法1:
找到了我就返回位置,否則我就返回-1。
int search1(){
for (int i = 0; i < MAXN; ++i){
if (nums[i] == VALUE){
return i;
}
}
return -1;
}
現在問題來了,演算法效率差一點點,入股能優化8%那就可以用了,怎麼辦?
大家也許還記得,比較運算子是非常耗時的,我們如果不用比較運算子,同樣的線性演算法,也許有可能有些優化,多少呢?
我實現了一下,8%左右問題不大,程式碼附在後面,search2()。
那萬一還不行,依舊是這個演算法,我們要做到之前時間的3分之一,怎麼辦?
別急別急,法子簡單的很,就是把++i去掉,把中間的部分手寫8次,然後每次i+=8,你還真別不信,我實現之後,耗時只有之前的四分之一左右!!!!!。程式碼附在後面search3中。
為啥呢?因為將迴圈展開有助於避免管道阻塞,減少分支,增加指令級的並行性。下面是實驗結果:
time1=0.075000
time2=0.069000
優化= 8%
time3=0.021000
優化= 72%
[Finished in 1.4s]
完整程式碼如下:
#include <iostream>
#include <cstdio>
#include <ctime>
using namespace std;
int nums[51000000];
const int POSITION = 40000000;
const int MAXN = 50000000;
const int VALUE = 2;
int search1();
int search2();
int search3();
clock_t start, end;
int main(){
for (int i = 0; i < MAXN; ++i){
nums[i] = 1;
}
nums[POSITION] = 2;
start = clock();
search1();
end = clock();
double time1 = (double)(end-start)/CLK_TCK;
printf("time=%f\n",(double)(end-start)/CLK_TCK);
start = end = 0;
start = clock();
search2();
end = clock();
double time2 = (double)(end-start)/CLK_TCK;
printf("time=%f\n",(double)(end-start)/CLK_TCK);
cout << (time1 - time2) / time1 * 100 << endl;
start = clock();
search3();
end = clock();
double time3 = (double)(end-start)/CLK_TCK;
printf("time=%f\n",(double)(end-start)/CLK_TCK);
cout << (time1 - time3) / time1 * 100 << endl;
return 0;
}
int search1(){
for (int i = 0; i < MAXN; ++i){
if (nums[i] == VALUE){
return i;
}
}
return -1;
}
int search2(){
int hold = nums[MAXN -1];
nums[MAXN - 1] = INT_MAX;
int i;
for (i = 0; ; i += 1){
if (nums[i] == VALUE){
break;
}
}
nums[MAXN - 1] = hold;
if (i == MAXN - 1){
return -1;
}
return i;
}
int search3(){
int hold = nums[MAXN -1];
nums[MAXN - 1] = INT_MAX;
int i;
for (i = 0; ; i += 8){
if (nums[i] == VALUE){
break;
}
if (nums[i + 1] == VALUE){
i += 1;
break;
}
if (nums[i + 2] == VALUE){
i += 2;
break;
}
if (nums[i + 3] == VALUE){
i += 3;
break;
}
if (nums[i + 4] == VALUE){
i += 4;
break;
}
if (nums[i + 5] == VALUE){
i += 5;
break;
}
if (nums[i + 6] == VALUE){
i += 6;
break;
}
if (nums[i + 7] == VALUE){
i += 7;
break;
}
}
nums[MAXN - 1] = hold;
if (i == MAXN - 1){
return -1;
}
return i;
}
相關文章
- 《程式設計珠璣》程式碼之路15:節省空間的常見姿勢程式設計
- 《程式設計珠璣》程式碼之路11:最大子陣列和問題,花式七種解法程式設計陣列
- 《程式設計珠璣》程式碼之路12:如何用C/C++實現array[-1]並利用它寫出優美的程式碼程式設計C++
- 《程式設計珠璣》程式碼之路13:陣列如何線上性時間內實現多次區間修改程式設計陣列
- 有關程式碼執行效率提升的小例子
- 兩個程式設計師老友的會面程式設計師
- 程式設計師提升學習效率的3個方法,影響過整個世界程式!程式設計師
- 小程式助力提升運維效率運維
- 39個史詩級奇葩程式碼註釋,程式不會崩,但程式設計師會!程式設計師
- 不會填坑的程式設計師不是一個好程式設計師!程式設計師
- Flink程式設計套路程式設計
- 不會程式設計也可以製作ERP、CRM系統。程式設計
- 程式設計技巧│提高 Javascript 程式碼效率的技巧程式設計JavaScript
- 風變程式設計——小白也能學會的程式設計課!程式設計
- 不會演算法的音樂家,不是一個好程式設計師演算法程式設計師
- 面試了一個 5 年 Java 程式設計師,一個問題也不會。。面試Java程式設計師
- 使用小程式助力提升運維效率!運維
- 兩個最多可以提高千倍效率的Go語言程式碼小技巧Go
- 程式設計師修煉之路 - 設計能力提升途徑程式設計師
- 在Python程式設計面試前需要學會的10個演算法(附程式碼)Python程式設計面試演算法
- iOS面試珠璣iOS面試
- 不會git的程式設計師,會不會被鄙視?Git程式設計師
- 每個程式設計師都會的 35 個 jQuery 小技巧程式設計師jQuery
- 一個老程式設計師的程式設計之路,寫給年輕的程式設計師們程式設計師
- 5位女性程式設計師的自白:計算機不撒謊;女程式設計師的程式碼一樣也很棒程式設計師計算機
- 老程式設計師的10個程式設計小技巧,教你寫出高質量程式碼!程式設計師
- 好程式設計師不寫程式碼程式設計師
- 提升開發效率,程式設計師都在使用的免費api程式設計師API
- Java程式設計小技巧(1)——方法傳回兩個物件Java程式設計物件
- 分享兩個小程式
- 提升開發效率,小程式容器來幫你
- 我的程式設計之路程式設計
- 程式設計師如何能把一個功能說的工作量很大?程式設計師
- "無程式碼開發"會不會是未來程式設計的一大趨勢?程式設計
- 程式設計師的成長秘籍:個人程式設計能力的修煉之路程式設計師
- 程式設計師職場之路,如何提升技術能力?程式設計師
- 學習風變程式設計,學會的不僅僅是程式設計程式設計
- “程式設計不規範,同事兩行淚!”程式設計