日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MATLAB中代码优化的两种方法

發(fā)布時(shí)間:2025/4/5 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MATLAB中代码优化的两种方法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

MATLAB中的代碼優(yōu)化

MATLAB中的代碼優(yōu)化有兩種重要的方法:預(yù)分配組和向量化循環(huán)

我們舉一個(gè)簡(jiǎn)單的例子來看,創(chuàng)建一個(gè)MATLAB函數(shù)來計(jì)算f(x) = sin(x / 100π):

function y = sinfun1(M) x = 0: M - 1; for k = 1: numel(x)y(k) = sin(x(k) / (100 * pi)); end

這里 我們使用函數(shù)timeit來計(jì)算調(diào)用函數(shù)所需的時(shí)間。(timeit可用于得到函數(shù)調(diào)用的可靠的、可重復(fù)的時(shí)間測(cè)量。)

此時(shí)我們得到M數(shù)量級(jí)為20000時(shí)的時(shí)間測(cè)量,如圖1所示:

圖1 函數(shù)sinfun1在M=20000的時(shí)間測(cè)量

我們?cè)诰帉懲旰瘮?shù)sinfun1后可以看到MATLAB編輯器給出了一個(gè)提示:變量’y’似乎會(huì)隨迭代次數(shù)而改變,請(qǐng)預(yù)分配內(nèi)存以獲得更高的運(yùn)算速度。

為什么會(huì)出現(xiàn)這樣的情況?那是因?yàn)樵趕infun1這個(gè)函數(shù)中,輸出變量y每經(jīng)過一次循環(huán)后都會(huì)增長一個(gè)元素大小,它必須重新分配新的存儲(chǔ)空間,并且在每次數(shù)組生長時(shí)都要復(fù)制前一組數(shù)組元素。這種頻繁的內(nèi)存重新分配和復(fù)制的開銷非常大,與sin本身的計(jì)算相比需要更多的時(shí)間。

此時(shí)我們采用預(yù)分配數(shù)組的辦法進(jìn)行嘗試:

預(yù)分配組:是指在進(jìn)入一個(gè)計(jì)算數(shù)組元素的for循環(huán)之前,初始化數(shù)組。預(yù)分配就意味著咋循環(huán)開始之前把它初始化為所希望的輸出大小。

function y = sinfun2(M) x = 0: M - 1; y = zeros(1, numel(x)); for k = 1: numel(x)y(k) = sin(x(k) / (100 * pi)); end

在這里我們使用了zeros生成一個(gè)矩陣來預(yù)分配存儲(chǔ)空間,然后調(diào)用timeit計(jì)算M=20000時(shí)候的時(shí)間測(cè)量,如圖2:

圖1 函數(shù)sinfun2在M=20000的時(shí)間測(cè)量
通過對(duì)比可以得出,在M=20000的數(shù)量級(jí)下,使用預(yù)分配數(shù)組的辦法,要比不使用運(yùn)行快4倍。
接下來我們?cè)贛的數(shù)量級(jí)為200000和2000000下對(duì)兩種方法進(jìn)行比較,得出的結(jié)果如圖3,圖4所示:

圖3 兩種方法在M=200000下的時(shí)間測(cè)量

圖4 兩種方法在M=2000000下的時(shí)間測(cè)量
我們通過計(jì)算可以得出,函數(shù)sinfun1基本維持了所要求的的時(shí)間與M成正比,sinfun2則在數(shù)量級(jí)到了一定程度后維持正比。另外比較兩個(gè)函數(shù)在200000和2000000下的速度比,可見在這兩個(gè)數(shù)量級(jí)下預(yù)分配數(shù)組的方法大約要比sinfun1快6倍。

向量化循環(huán)是指使用矩陣/向量運(yùn)算符、索引技術(shù)和現(xiàn)有的MATLAB或工具箱函數(shù)來完全消除循環(huán)的一種技術(shù)。

我們使用向量化循環(huán)對(duì)矩陣的輸入進(jìn)行逐元素的操作來消除循環(huán):

function y = sinfun3(M) x = 0: M - 1; y = sin(x ./ (100 * pi)); end

此時(shí)我們?cè)儆胻imit在M=20000時(shí)進(jìn)行時(shí)間測(cè)量,如圖5:

圖5 函數(shù)sinfun3在M=20000的時(shí)間測(cè)量

由圖可知我們使用向量化時(shí),在M=20000時(shí)要比預(yù)分配數(shù)組快3倍。接下來測(cè)量M的數(shù)量級(jí)為200000和2000000的時(shí)間。如圖6所示:

圖6 函數(shù)sinfun3在M=200000和2000000的時(shí)間測(cè)量
由此可見,不帶循環(huán)sinfun3的執(zhí)行速度和帶一個(gè)循環(huán)的sinfun2的執(zhí)行速度大致相同,但又略快于sinfun2。

在教材中為了為了更好地說明這個(gè)比較兩種優(yōu)化方法,給出了下面這個(gè)例子。

這個(gè)例子是基于公式f(x) = Asin(u0x + v0y)創(chuàng)建一幅合成圖像,首先使用嵌套的for循環(huán)來計(jì)算f:

function f = twodsin1(A, u0, v0, M, N) %f = zeros(M, N); for c = 1 : Nv0y = v0 * (c - 1);for r = 1 : Mu0x = u0 * (r - 1);f(r, c) = A * sin(u0x + v0y);end end

不使用預(yù)分配和使用后的執(zhí)行時(shí)間如圖7所示:

圖7 函數(shù)twodsin1使用預(yù)分配的前后比較


我們?cè)谶@里發(fā)現(xiàn)使用預(yù)分配前后,執(zhí)行時(shí)間的差距并沒有很大。接下來來看向量化后的結(jié)果。

在實(shí)驗(yàn)中使用一個(gè)meshgrid的MATLAB函數(shù)將函數(shù)重寫為沒有for循環(huán)的形式。

function f = twodsin2(A, u0, v0, M, N) r = 0 : M - 1; c = 0 : N - 1; [C, R] = meshgrid(c, r); f = A * sin(u0 * R + v0 * C);

繼續(xù)用timeit測(cè)試,得到的結(jié)果如圖8:

圖8 函數(shù)twodsin2的時(shí)間測(cè)量


可見使用向量化后,比使用預(yù)分配快了30%,比不使用任何優(yōu)化方法快了50%。

小結(jié)

綜合以上兩個(gè)實(shí)驗(yàn)表明,兩種代碼優(yōu)化方法(預(yù)分配數(shù)組和向量化循環(huán))在具體的使用中的差別并不是很大,都可以提升循環(huán)運(yùn)行的速度。我們可以在遇到具體問題后,根據(jù)具體情況選擇具體的方法:若是循環(huán)存在沒有預(yù)分配內(nèi)存的問題,那我們可以考慮采用預(yù)分配的方法,這樣對(duì)代碼的改動(dòng)不大,更直觀,也更容易表示我們代碼得到實(shí)際工作機(jī)理;若是確定沒有預(yù)分配的問題,就可以選擇向量化循環(huán)的辦法,這樣與基于循環(huán)的代碼相比,向量化后的代碼更易于閱讀,更為簡(jiǎn)潔。

總結(jié)

以上是生活随笔為你收集整理的MATLAB中代码优化的两种方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。