我目前使用md5_file()
來運行約15個URL並驗證它們的MD5散列值。有什麼方法可以讓這個更快?貫穿它們需要很長的時間。使md5_file()更快的方法?
回答
也許你現在正在按順序進行。即獲取數據1,處理數據1,獲取數據2,處理數據2 ...,瓶頸可能是數據傳輸。
你可以使用curl_multi_exec()來平行一點。 要麼註冊CURLOPT_WRITEFUNCTION並處理每個數據塊(由於md5()只處理一個數據塊,所以很棘手)。
或檢查已完成的捲曲手柄,然後處理該手柄的數據。
編輯:使用hash extension(其中增量散列函數提供)和php5.3+ closure快速&骯髒的例子:
$urls = array(
'http://stackoverflow.com/',
'http://sstatic.net/so/img/logo.png',
'http://www.gravatar.com/avatar/212151980ba7123c314251b185608b1d?s=128&d=identicon&r=PG',
'http://de.php.net/images/php.gif'
);
$data = array();
$fnWrite = function($ch, $chunk) use(&$data) {
foreach($data as $d) {
if ($ch===$d['curlrc']) {
hash_update($d['hashrc'], $chunk);
}
}
};
$mh = curl_multi_init();
foreach($urls as $u) {
$current = curl_init();
curl_setopt($current, CURLOPT_URL, $u);
curl_setopt($current, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($current, CURLOPT_HEADER, 0);
curl_setopt($current, CURLOPT_WRITEFUNCTION, $fnWrite);
curl_multi_add_handle($mh, $current);
$hash = hash_init('md5');
$data[] = array('url'=>$u, 'curlrc'=>$current, 'hashrc'=>$hash);
}
$active = null;
//execute the handles
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active && $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
foreach($data as $d) {
curl_multi_remove_handle($mh, $d['curlrc']);
echo $d['url'], ': ', hash_final($d['hashrc'], false), "\n";
}
curl_multi_close($mh);
(還沒有檢查的結果,雖然......這只是一個起點)
+1。並行下載可能是一個巨大的勝利。你也可以通過使用'md5sum' CLI命令(例如'exec('bash -c「md5sum file1> file1.md5&'')'),或者使用類似PHP的pcntl_fork()來實現md5部分的並行化。將多個調用分叉到md5_sum()。這些都有它們的缺點,但是在正確的背景下,它們可能是最好的選擇。 – 2010-05-01 15:01:23
我必須承認,我甚至沒有測試下載是否真的繼續執行回調。但由於數據部分應該很小,所以我希望它不重要(很多)。 – VolkerK 2010-05-01 15:26:05
md5算法的速度幾乎可以達到,獲取網址的速度幾乎可以達到(如果文件很大或連接速度較慢,速度會變慢)。所以不行。你無法讓速度更快。
那麼顯然,你不能做md5_file()
任何事情,使速度更快,但是,你可以使用一些micro-optimizations或代碼重新分解得到一些速度增益,但你又不能加快內置函數md5_file()
。
......當然,一些微型優化可能會削減2毫秒的運行時間。也許。或者他可以並行拖動網址並保存幾秒鐘。 「微觀優化」幾乎是不值得的。 – 2010-05-01 14:57:54
@Frank,這是在編輯問題之前發佈的,它實際上包含了問題代碼(直到添加代碼之前,基本上詢問如何加速md5_file())。 – 2010-05-01 15:16:06
不可以。因爲這是內置函數,所以無法使其更快。
但是,如果您的代碼在MD5之前下載文件,可能會優化您的下載速度。如果您事先知道大小,則在寫入文件之前(使用ftruncate)設置文件的大小也可能會看到小的速度增加。另外,如果文件足夠小以容納內存,並且你已經將它們存儲在內存中(因爲它們已經被下載,或者正在爲其他目的而被讀取),那麼你可以使用md5
在內存中對其進行操作而不是md5_file
,這需要從磁盤再次讀取。
假設您在一段時間內檢查了相同的URL?你可以檢查URL的最後修改標題嗎?如果被檢查的頁面沒有改變,那麼就不需要重新計算MD5。
您也可以異步請求頁面,以便它們可以並行處理,而不是以串行方式處理,這會加快處理速度。
MD5算法的速度是線性的。輸入越大,需要的時間就越多,所以如果文件很大,真的沒有太多可以做的事情。
現在,正如VolkerK已經提出的那樣,問題很可能不是md5散列,而是通過網絡檢索和讀取文件。
我看到一個非常好的建議,優化here。這對於大文件尤其適用,其中md5_file正在讀取文件,而此函數僅比較每個文件的第二個字節。
解釋你想要做什麼會有所幫助。 如果你想驗證文件的MD5散列:
這不是一個安全的方法,因爲它很容易Collision attack。您應該使用多個哈希(可能通過分割文件)或使用其他哈希方法。
- 1. 查看遠程文件是否比md5_file更改的更快方法()
- 2. 更快的搜索方法
- 3. :有更快的方法嗎?
- 4. 更快的保存方法?
- 5. md5_file()不與URL
- 6. 哪種方法更快?
- 7. 有沒有更快的方法?
- 8. 大規模更新的最快方法
- 9. 更新最快的方法:update()或save()?
- 10. 替代更快的方法fscanf在c + +?
- 11. 更快的循環方法('for'和'foreach')?
- 12. 重塑數據(更快的方法)
- 13. Python更快的方法做排列
- 14. 更快的方法來分開列表
- 15. 獲取SQL語句的方法更快
- 16. 獲得多個FileInfo的更快方法?
- 17. SQL - 最快的方法來更新
- 18. 更快的方法子集xts
- 19. 更快的ExtJs 4學習方法
- 20. 更快的方法來比較2 UserProfileValueCollection
- 21. 更快的方式
- 22. 使用md5_file();有時不返回md5?
- 23. 更快速的方法來執行方法參數檢查
- 24. 更快的方法來使DataGridViewRow的不可見
- 25. 有更快的方法來檢查使用AS3的BitmapData.getPixel32()嗎?
- 26. 我的$ .each循環很慢。任何使其更快的方法?
- 27. 更快的算法
- 28. 更快速地創建測試方法
- 29. GET方法比POST更快嗎?
- 30. 什麼轉換爲str方法更快?
「遍歷約15個URL」是指類似'md5_file('http://some.url/foo')'在一個循環中與15個不同的URL?這些「文件」有多大? – VolkerK 2010-05-01 14:17:03
是的,就是這樣。我將它們從MySQL數據庫中提取出來,然後在循環中運行它們到md5_file($ result)中。這些文件非常小,實際上沒有顯示輸出,沒有用戶界面,查看時只是一個空白的白頁 – Rob 2010-05-01 14:19:25
問題是,你是按順序計算哈希值而不是平行計算哈希值, 'md5_file'不是瓶頸。另外,一個空文件的哈希值肯定是一樣的。 – salathe 2010-05-01 14:38:12