优化if语句、计算、会话查询
Posted
技术标签:
【中文标题】优化if语句、计算、会话查询【英文标题】:Optimising if statement, calculation, session query 【发布时间】:2021-12-16 02:12:39 【问题描述】:目前,我正在尝试用我 2 年的业余爱好在 python 中编写脚本来优化我的旧代码。
对于过去的脚本,我检查了是否向玩家提供资源。 100.000 的整个计算确实需要大约 25 分钟。如果资源等于最大存储空间,它将不会从表中获取行。
如果 3 种资源类型中的一种已满,仍会进行检查(因此其他资源将获得其生产奖励。
生产分为 4 个,因为它会在 15 分钟内运行一次。
旧代码的运行时间为 25 分钟。 下面显示的代码确实在 1 分 40 秒内运行了超过 100,000 个“村庄”。 2.3秒撤回所有数据 0,2 秒将所有数据写入数据库 剩下的时间(1 分 37.5 秒)纯粹是介于两者之间的时间
对于村庄中的村庄:和 session.add(add_resources)
是否有可能进一步加快速度,或者这些是 Python 本身的限制?
time_start, villages = datetime.utcnow(), new_get_villages()
for village in villages:
production_wood, production_stone, production_iron = int(village.wood_production/4), int(village.stone_production/4), int(village.iron_production/4)
add_resources = session.query(VillageNew).filter(VillageNew.pk == village.pk).first()
if add_resources.wood_stock != add_resources.max_storage:
add_resources.wood_stock = add_resources.wood_stock + production_wood
if add_resources.wood_stock > add_resources.max_storage:
add_resources.wood_stock = add_resources.max_storage
if add_resources.stone_stock != add_resources.max_storage:
add_resources.stone_stock = add_resources.stone_stock + production_stone
if add_resources.stone_stock > add_resources.max_storage:
add_resources.stone_stock = add_resources.max_storage
if add_resources.iron_stock != add_resources.max_storage:
add_resources.iron_stock = add_resources.iron_stock + production_iron
if add_resources.iron_stock > add_resources.max_storage:
add_resources.iron_stock = add_resources.max_storage
session.add(add_resources)
session.commit
time_end = datetime.utcnow()
会话:
db_connection_string = conf.get_string('DBConf', 'db_connection_string')
engine = create_engine(db_connection_string, encoding='utf8')
Session = sessionmaker(bind=engine)
@gimix 发帖后代码更新
for village in session.query(VillageNew).filter(or_(VillageNew.wood_stock != VillageNew.max_storage, VillageNew.stone_stock != VillageNew.max_storage, VillageNew.iron_stock != VillageNew.max_storage)).all():
village.wood_stock = (village.wood_stock + int(village.wood_production))
if village.wood_stock > village.max_storage:
village.wood_stock = village.max_storage
village.stone_stock = (village.stone_stock + int(village.wood_production))
if village.stone_stock > village.max_storage:
village.stone_stock = village.max_storage
village.iron_stock = (village.iron_stock + int(village.wood_production))
if village.iron_stock > village.max_storage:
village.iron_stock = village.max_storage
session.commit()
代码更新 2021 年 2 月 11 日:
session.query(VillageNew).where(VillageNew.wood_stock < VillageNew.max_storage).update(VillageNew.wood_stock: VillageNew.wood_stock + VillageNew.wood_production)
session.query(VillageNew).where(VillageNew.stone_stock < VillageNew.max_storage).update(VillageNew.stone_stock: VillageNew.stone_stock + VillageNew.stone_production)
session.query(VillageNew).where(VillageNew.iron_stock < VillageNew.max_storage).update(VillageNew.iron_stock: VillageNew.iron_stock + VillageNew.iron_production)
session.query(VillageNew).where(VillageNew.wood_stock > VillageNew.max_storage).update(VillageNew.wood_stock: VillageNew.max_storage)
session.query(VillageNew).where(VillageNew.stone_stock > VillageNew.max_storage).update(VillageNew.stone_stock: VillageNew.max_storage)
session.query(VillageNew).where(VillageNew.iron_stock > VillageNew.max_storage).update(VillageNew.iron_stock: VillageNew.max_storage)
【问题讨论】:
问题是什么? 是否可以进一步加快速度,或者这些是 Python 本身的限制吗?我太忙于确保摘要是否正确而忘记了问题。 什么是session
(数据库?SaaS?内部部署?)?
Session 是与数据库的连接。在测试期间,数据库和运行脚本在同一台机器上,当进入生产环境时,也将在同一台服务器上。我已将会话添加到主帖
你有一堆 if
s 但是如果你 timeit
使用简单的变量,你会发现你所有的测试在 100 万次迭代中花费的时间不到 1 秒 - 所以问题出在 SqlAlchemy .也许this post 有帮助?
【参考方案1】:
最后最快的是纯 SQL 执行。
session.execute('UPDATE table.villagenew SET wood_stock = least(villagenew.wood_stock + villagenew.wood_production, villagenew.max_storage) WHERE villagenew.wood_stock < villagenew.max_storage')
如果需要对程序的反馈,如已满:
session.query(VillageNew).where(VillageNew.wood_stock < VillageNew.max_storage).update(VillageNew.wood_stock: VillageNew.wood_stock + VillageNew.wood_production) session.query(VillageNew).where(VillageNew.stone_stock < VillageNew.max_storage).update(VillageNew.stone_stock: VillageNew.stone_stock + VillageNew.stone_production) session.query(VillageNew).where(VillageNew.iron_stock < VillageNew.max_storage).update(VillageNew.iron_stock: VillageNew.iron_stock + VillageNew.iron_production) session.query(VillageNew).where(VillageNew.wood_stock > VillageNew.max_storage).update(VillageNew.wood_stock: VillageNew.max_storage) session.query(VillageNew).where(VillageNew.stone_stock > VillageNew.max_storage).update(VillageNew.stone_stock: VillageNew.max_storage) session.query(VillageNew).where(VillageNew.iron_stock > VillageNew.max_storage).update(VillageNew.iron_stock: VillageNew.max_storage)
【讨论】:
以上是关于优化if语句、计算、会话查询的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript 与 coffescript 语法 - if 条件:优化 if 语句结构