优化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 是与数据库的连接。在测试期间,数据库和运行脚本在同一台机器上,当进入生产环境时,也将在同一台服务器上。我已将会话添加到主帖 你有一堆 ifs 但是如果你 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 &lt; villagenew.max_storage')

如果需要对程序的反馈,如已满session.query(VillageNew).where(VillageNew.wood_stock &lt; VillageNew.max_storage).update(VillageNew.wood_stock: VillageNew.wood_stock + VillageNew.wood_production) session.query(VillageNew).where(VillageNew.stone_stock &lt; VillageNew.max_storage).update(VillageNew.stone_stock: VillageNew.stone_stock + VillageNew.stone_production) session.query(VillageNew).where(VillageNew.iron_stock &lt; VillageNew.max_storage).update(VillageNew.iron_stock: VillageNew.iron_stock + VillageNew.iron_production) session.query(VillageNew).where(VillageNew.wood_stock &gt; VillageNew.max_storage).update(VillageNew.wood_stock: VillageNew.max_storage) session.query(VillageNew).where(VillageNew.stone_stock &gt; VillageNew.max_storage).update(VillageNew.stone_stock: VillageNew.max_storage) session.query(VillageNew).where(VillageNew.iron_stock &gt; VillageNew.max_storage).update(VillageNew.iron_stock: VillageNew.max_storage)

【讨论】:

以上是关于优化if语句、计算、会话查询的主要内容,如果未能解决你的问题,请参考以下文章

jq代码优化,如何优化大量的if elseif语句

使用 if 语句重用 count

JavaScript 与 coffescript 语法 - if 条件:优化 if 语句结构

优化if -else语句问[关闭]

一万个if..........else....语句,请问如何去优化它。。。。以提升性能效率

Java 感觉在try语句中嵌套if语句不怎么美观,请问怎么优化