Python Flask应用处理大数据时冻结,寻求优化建议
问题分析与解决方案
核心问题原因
你的Flask应用处理大数据集时冻结,本质是采用了暴力枚举所有数字组合的逻辑(时间复杂度O(2ⁿ)),当输入值数量达到100时,计算量呈指数级爆炸,无法在合理时间内完成,同时阻塞了Flask单线程的请求处理流程,导致整个应用无响应。
具体改进方案
1. 替换为高效的子集和算法(动态规划)
放弃暴力枚举,改用动态规划求解子集和问题,时间复杂度优化为O(n×target),可轻松支持100个以上输入值:
def find_combinations(nums, target): # 预处理:去重+排序,减少重复计算 nums = sorted(list(set(nums))) # dp[i]存储所有和为i的数字组合 dp = [[] for _ in range(target + 1)] dp[0] = [[]] for num in nums: # 倒序遍历避免重复使用同一元素(允许重复则改为正序) for i in range(target, num - 1, -1): for combo in dp[i - num]: dp[i].append(combo + [num]) # 去重重复组合 unique_combinations = [] seen = set() for combo in dp[target]: sorted_combo = tuple(sorted(combo)) if sorted_combo not in seen: seen.add(sorted_combo) unique_combinations.append(list(sorted_combo)) return unique_combinations
2. 实现异步请求处理,避免应用冻结
Flask默认单线程模式下,长时间计算会阻塞所有请求。用Celery+Redis实现异步任务,让用户提交请求后等待结果,而非页面卡死:
- 安装依赖:
pip install celery redis - 核心代码配置:
# celery_config.py from celery import Celery def make_celery(app): celery = Celery( app.import_name, backend='redis://localhost:6379/0', broker='redis://localhost:6379/0' ) celery.conf.update(app.config) return celery # app.py from flask import Flask, request, jsonify from celery_config import make_celery app = Flask(__name__) app.config['CELERY_BROKER_URL'] = 'redis://localhost:6379/0' app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost:6379/0' celery = make_celery(app) @celery.task def compute_combinations_task(nums, target): return find_combinations(nums, target) @app.route('/submit', methods=['POST']) def submit(): data = request.json nums = data['nums'] target = data['target'] task = compute_combinations_task.delay(nums, target) return jsonify({'task_id': task.id}) @app.route('/result/<task_id>') def get_result(task_id): task = compute_combinations_task.AsyncResult(task_id) if task.state == 'SUCCESS': return jsonify({'result': task.result}) else: return jsonify({'state': task.state})
3. 前端配套优化
修改输入页面,提交请求后显示加载动画,通过轮询/result/<task_id>接口获取计算结果,避免页面无响应。
4. PythonAnywhere部署适配
- 启用Redis服务:在PythonAnywhere控制台启动Redis,或使用平台提供的Redis附加服务
- 启动Celery worker:后台执行命令
celery -A app.celery worker --loglevel=info - 替换Flask内置服务器:用Gunicorn部署,命令为
gunicorn app:app,支持多线程处理请求
额外优化建议
- 输入预处理:自动过滤大于目标值的数字,减少无效计算
- 结果分页:若组合数量过多,返回分页结果,降低前端渲染压力
- 进度提示:在Celery任务中记录计算进度,前端实时显示进度状态
内容的提问来源于stack exchange,提问作者koravik
相关产品推荐
相关产品推荐

