網(wǎng)站首頁 編程語言 正文
一、時間不一致的猜想
python腳本運行時間遠遠大于python腳本中統(tǒng)計的計算時間
猜想:
1.python中用到的是py2neo的寫數(shù)據(jù)異步,阻塞進程運行;
2.python腳本使用統(tǒng)計時間的方式是time.clock(),而這種方式統(tǒng)計的是CPU的執(zhí)行時間,不是程序的執(zhí)行時間。
程序執(zhí)行時間 = CPU運行時間 + IO時間 + 休眠或等待時間
二、原因探索
1.方法一
import asyncio
import datetime
starttime = datetime.datetime.now()
# long running
# do something other
async def sayhi():
print("你好,若竹")
await asyncio.sleep(10)
print("用余生去守護")
asyncio.run(sayhi())
endtime = datetime.datetime.now()
print(("程序運行時間為:")+ str((endtime-starttime).seconds)+"秒")
輸出:
你好,若竹
用余生去守護
程序運行時間為:10秒
datetime.datetime.now()獲取的是當(dāng)前日期,在程序執(zhí)行結(jié)束之后,這個方式獲得的時間值為程序執(zhí)行的時間。
2.方法二
import asyncio
import datetime
import time
starttime = time.time()
# long running
# do something other
async def sayhi():
print("你好,若竹")
await asyncio.sleep(10)
print("用余生去守護")
asyncio.run(sayhi())
endtime = time.time()
print("程序運行時間為:"+ str(float(endtime-starttime))+"秒")
輸出:
你好,若竹
用余生去守護
程序運行時間為:10.002257108688354秒
time.time()獲取自紀元以來的當(dāng)前時間(以秒為單位)。如果系統(tǒng)時鐘提供它們,則可能存在秒的分數(shù),所以這個地方返回的是一個浮點型類型。這里獲取的也是程序的執(zhí)行時間。
3.方法三
import asyncio
import datetime
import time
starttime = time.clock()
# long running
# do something other
async def sayhi():
print("你好,若竹")
await asyncio.sleep(10)
print("用余生去守護")
asyncio.run(sayhi())
endtime = time.clock()
print("程序運行時間為:"+ str(float(endtime-starttime))+"秒")
輸出:
.\py_study.py:807: DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead
? starttime = time.clock()
你好,若竹
用余生去守護
.\py_study.py:818: DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead
? endtime = time.clock()
程序運行時間為:10.0219916秒
Deprecation Warning: time. clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time. perf_counter or time. process_time instead
棄用警告:時間。clock在Python 3.3中已棄用,并將從Python 3.8中移除:使用time。perf_counter或時間。process_time代替。
代碼如下:
import asyncio
import datetime
import time
starttime = time.perf_counter()
# long running
# do something other
async def sayhi():
print("你好,若竹")
await asyncio.sleep(10)
print("用余生去守護")
asyncio.run(sayhi())
endtime = time.perf_counter()
print("程序運行時間為:"+ str(float(endtime-starttime))+"秒")
輸出:
你好,若竹
用余生去守護
程序運行時間為:10.060287599999999秒
三、python 運行效率慢的原因
1.簡介
編程語言的效率一方面指開發(fā)效率,即程序員完成編碼所需的時間,另一方面是運行效率,即計算任務(wù)所需的時間。編碼效率和運行效率往往很難兼顧。
2.運行效率慢的原因
1.python 是動態(tài)語言,造成運行時的不確定性影響運行效率;
動態(tài)語言是一類在運行時可以改變其結(jié)構(gòu)的語言,如新的函數(shù)、對象、代碼可以被引入,已有的函數(shù)可以被刪除或其他結(jié)構(gòu)上的變化等,該類語言更具有活性,但是不可避免的因為運行時的不確定性也影響運行效率。數(shù)據(jù)的比較和轉(zhuǎn)換類型的開銷很大,每次讀取、寫入或引用一個變量,都要檢查類型。很難優(yōu)化一種極具動態(tài)性的語言。Python的許多替代語言之所以快得多,原因在于它們?yōu)榱诵阅茉陟`活性方面作出了犧牲。
2.python 是解釋執(zhí)行,不支持JIT(just in time compiler);
相比于C語言編譯性語言編寫的程序,Python是解釋執(zhí)行語言,其運行過程是Python運行文件程序時,Python解釋器將源代碼轉(zhuǎn)換為字節(jié)碼,然后再由Python解釋器來執(zhí)行這些字節(jié)碼。其每次運行都要進行轉(zhuǎn)換成字節(jié)碼,然后再由虛擬機把字節(jié)碼轉(zhuǎn)換成機器語言,最后才能在硬件上運行,與編譯性語言相比,其過程更復(fù)雜,性能肯定會受影響。
3.python 中一切皆對象,每個對象都需要維護引用計數(shù),增加額外工作;
Python是一門面向?qū)ο蟮木幊陶Z言,其設(shè)計理念是一切皆是對象,如數(shù)字、字符串、元組、列表、字典、函數(shù)、方法、類、模塊等都是對象,包括代碼,每個對象都需要維護引用計數(shù),因此,增加了額外工作,影響了性能。
4.python GIL,全局解釋器鎖導(dǎo)致無法實現(xiàn)真正的并發(fā);
GIL是Python最為詬病的一點,因為GIL,Python中的多線程并不能真正的并發(fā),即使在單線程,GIL也會帶來很大的性能影響,因為python每執(zhí)行100個opcode就會嘗試線程的切換,因此,影響Python運行效率。
5.垃圾回收機制,會中斷正在執(zhí)行的程序,造成所謂的卡頓;
Python采用標記和分代的垃圾回收策略,每次垃圾回收的時候都會中斷正在執(zhí)行的程序,造成所謂的頓卡,影響運行效率。
四、python 優(yōu)化
1.優(yōu)化算法:時間復(fù)雜度
算法的時間復(fù)雜度對程序的執(zhí)行效率影響最大,在python 中可以通過選擇合適的數(shù)據(jù)結(jié)構(gòu)來優(yōu)化時間復(fù)雜度,如list和set查找某一個元素的時間復(fù)雜度分別是O(n)和O(1).不同的場景有不同的優(yōu)化方式,總的來說,一般有分治,分支界限,貪心,動態(tài)規(guī)劃等。
20減少冗余數(shù)據(jù)
如用上三角或下三角的方式去保存一個大的對稱矩陣。在0元素占大多數(shù)的矩陣里使用稀疏矩陣表示。
3.合理使用copy與deepcopy
對于dict和list等數(shù)據(jù)結(jié)構(gòu)的對象,直接賦值使用的是引用的方式。而有些情況下需要復(fù)制整個對象,這時可以使用copy包里的copy和deepcopy,這兩個函數(shù)的不同之處在于后者是遞歸復(fù)制的。效率也不一樣:(以下程序在ipython中運行)
4.使用dict或set查找元素
5.合理使用生成器(generator)和yield
6.優(yōu)化循環(huán)
7.優(yōu)化包含多個判斷表達式的順序
8.使用join合并迭代器中的字符串
9.選擇合適的格式化字符方式
10.不借助中間變量交換兩個變量的值
11.使用if is
12.使用級聯(lián)比較x < y < z
13.while 1 比 while True 更快
14.使用**而不是pow
15.使用 cProfile, cStringIO 和 cPickle等用c實現(xiàn)相同功能(分別對應(yīng)profile, StringIO, pickle)的包
16.使用最佳的反序列化方式
17.使用C擴展(Extension)
18.并行編程
19.終級大殺器:PyPy
20.使用性能分析工具
原文鏈接:https://blog.csdn.net/qq_45365214/article/details/126139372
相關(guān)推薦
- 2022-06-07 Pytorch上下采樣函數(shù)之F.interpolate數(shù)組采樣操作詳解_python
- 2023-01-27 React?useEffect的理解與使用_React
- 2023-05-29 SQLSERVER?語句交錯引發(fā)的死鎖問題案例詳解_MsSql
- 2023-03-05 Suspend函數(shù)與回調(diào)的互相轉(zhuǎn)換示例詳解_Android
- 2022-07-19 Compose中更靈活易用的TextField以及密碼輸入框
- 2022-07-27 利用Python中的內(nèi)置open函數(shù)讀取二進制文件_python
- 2022-05-22 C語言鏈接屬性的實踐應(yīng)用_C 語言
- 2022-01-31 git統(tǒng)計當(dāng)前項目代碼行數(shù)
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支