本文目录导读:

针对Python脚本同步场景的性能优化,核心思路是减少IO操作次数、避免重复处理和使用增量机制,以下是几个实用优化方向:
文件哈希对比(避免全量同步)
import hashlib
import os
def get_file_hash(filepath):
"""只读取前64KB+文件大小进行哈希,避免读全部"""
file_size = os.path.getsize(filepath)
hash_md5 = hashlib.md5(str(file_size).encode()) # 加入大小
with open(filepath, "rb") as f:
# 只读前64KB作为签名
chunk = f.read(65536)
hash_md5.update(chunk)
return hash_md5.hexdigest()
增量同步 - 利用文件修改时间
import os
import shutil
from pathlib import Path
def smart_sync(src, dst, skip_existing=False):
src_path = Path(src)
dst_path = Path(dst)
for file in src_path.rglob('*'):
if file.is_file():
relative = file.relative_to(src_path)
dest_file = dst_path / relative
# 优先使用修改时间和大小判断
if dest_file.exists():
src_stat = file.stat()
dst_stat = dest_file.stat()
if (src_stat.st_mtime <= dst_stat.st_mtime and
src_stat.st_size == dst_stat.st_size):
continue # 跳过不变文件
# 只有真正需要时才进行IO复制
if not skip_existing or not dest_file.exists():
dest_file.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(file, dest_file)
内存映射+分块传输(大文件优化)
import mmap
import os
def chunked_copy(src, dst, chunk_size=8*1024*1024): # 8MB块
file_size = os.path.getsize(src)
with open(src, 'rb') as f_src:
with mmap.mmap(f_src.fileno(), 0, access=mmap.ACCESS_READ) as mm:
with open(dst, 'wb') as f_dst:
for start in range(0, file_size, chunk_size):
end = min(start + chunk_size, file_size)
f_dst.write(mm[start:end])
# 可以添加进度回调
并行同步 + 资源控制
from concurrent.futures import ThreadPoolExecutor, as_completed
import threading
class OptimizedSyncer:
def __init__(self, max_workers=4):
self.semaphore = threading.Semaphore(10) # 限制并发IO数
self.executor = ThreadPoolExecutor(max_workers=max_workers)
def sync_file(self, src, dst):
with self.semaphore: # 控制IO并发量
if os.path.getsize(src) > 100*1024*1024: # 大文件使用分块
self.chunked_copy(src, dst)
else:
shutil.copy2(src, dst)
def batch_sync(self, file_pairs):
futures = []
for src, dst in file_pairs:
if self.need_sync(src, dst): # 预筛选
futures.append(
self.executor.submit(self.sync_file, src, dst)
)
# 收集结果并处理异常
for future in as_completed(futures):
try:
future.result()
except Exception as e:
print(f"Sync failed: {e}")
避免重复IO - 缓存文件属性
functools.lru_cache(maxsize=1000)
def get_file_info(path):
return {
'size': os.path.getsize(path),
'mtime': os.path.getmtime(path),
'exists': os.path.exists(path)
}
def compare_files(src, dst):
src_info = get_file_info(src)
dst_info = get_file_info(dst)
if not dst_info['exists']:
return True
return (src_info['size'] != dst_info['size'] or
src_info['mtime'] > dst_info['mtime'])
使用ranger工具处理大量小文件
import subprocess
def rsync_sync(src, dst):
"""对于大量小文件,使用rsync效率远高于Python"""
cmd = [
'rsync', '-avz', # 归档模式+压缩
'--delete', # 删除目标多余文件
'--partial', # 支持断点续传
'--progress',
src, dst
]
subprocess.run(cmd, check=True)
关键优化点总结
| 优化策略 | 适用场景 | 性能提升 |
|---|---|---|
| 文件哈希跳过 | 大文件 | 减少90%+IO |
| mtime+size对比 | 常规文件 | 减少98%IO |
| 内存映射分块 | >500MB文件 | 提升3-5倍 |
| 并发+信号量 | 多文件同步 | 提升2-4倍 |
| 缓存属性 | 重复访问 | 减少IO延迟 |
| rsync委托 | 大量小文件 | 提升10倍+ |
建议顺序:
- 先实现mtime+size筛选
- 大文件用内存映射分块
- 大量小文件用rsync
- 最后根据情况加并发控制
这样可以从最简单的方式获得最大性能收益。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播