我想优化Python函数的执行时间,该函数大量使用了内置的PHPhotoLibrary.requestAuthorization { (status) in
switch status {
case .authorized:
var addedPhotos: [Media] = []
let fetchOptions = PHFetchOptions()
let allPhotos = PHAsset.fetchAssets(with: fetchOptions)
print("Found \(allPhotos.count) images")
DispatchQueue.global(qos: .userInitiated).async {
allPhotos.enumerateObjects(options: .reverse, using: { (asset: PHAsset, ind: Int, stop: UnsafeMutablePointer<ObjCBool>) in
let media = Media()
media.asset = asset
media.location = asset.location
addedPhotos.append(media)
})
DispatchQueue.main.async {
completion(addedPhotos)
}
}
case .denied, .restricted:
showError(errorMessage: "User denied access to photos")
case .notDetermined:
showError(errorMessage: "Unknown")
}
}
实用程序。我的功能按原样运行,但是速度很慢。
datetime
在计算机上运行1,000,000次此函数大约需要40秒,因此我使用# Check if an ending date (stored in a YYYY-MM-DD string) is
# within range of a beginning date (in the same format). Two
# numbers, the min/max length, define how soon/distant the 2nd
# date can be from the 1st.
minDelayLength = 1
maxDelayLength = 999
def checkDateRange(dateStr1, dateStr2):
date1 = datetime.strptime(dateStr1, '%Y-%m-%d')
date2 = datetime.strptime(dateStr2, '%Y-%m-%d')
minLimit = date1 + timedelta(days=minDelayLength)
maxLimit = date1 + timedelta(days=maxDelayLength)
return minLimit <= date2 <= maxLimit
对函数的一次运行进行了分析,以查找性能问题。我发现它进行了大量的函数调用:
cProfile
有人对提高我的功能性能有建议吗?我可以假设函数的输入将始终是有效的(正确格式化),并且我可以假设最小/最大长度不会改变。
答案 0 :(得分:1)
您的代码最慢的部分是strptime
。如果您确定日期字符串的格式始终为YYYY-MM-DD
,则可以使用下面的方法,该方法使日期字符串的速度提高了11倍(在500000次调用中进行了测试)。
from datetime import datetime, timedelta, date
minDelayLength = timedelta(days=1)
maxDelayLength = timedelta(days=999)
def checkDateRange(dateStr1, dateStr2):
date1 = date(int(dateStr1[:4]), int(dateStr1[5:7]), int(dateStr1[8:10]))
date2 = date(int(dateStr2[:4]), int(dateStr2[5:7]), int(dateStr2[8:10]))
return date1 + minDelayLength <= date2 <= date1 + maxDelayLength