php - Laravel 8 中的无效循环,每次迭代所花费的时间与数组大小成正比
问题描述
在 Laravel 8 / PHP 8 中,我在 POST 中收到一个正文,转换数据,然后批量插入 TimescaleDB。
这是代码:
public function store(Request $request)
{
ini_set('max_execution_time', -1);
$body = $request->getContent();
$meter = json_decode($body, true);
$chunkSize = 1000;
$measures = $meter['Measures'];
$chunkedRaws = collect($measures)->chunk($chunkSize);
$ok = 0;
$nok = 0;
$initialTime = Carbon::now();
foreach ($chunkedRaws as $chunkNumber => $raws) {
$chunkTime = Carbon::now();
$rawsToInsert = [];
foreach ($raws as $k => $raw) {
$rawTime = Carbon::now();
array_push($rawsToInsert, new \App\Models\Raw([
'operation_id' => $meter['OperationID'],
'meter_id' => $meter['ID'],
'conso_prod' => $meter['ConsoProd'],
'timestep' => $meter['Timestep'],
'unit' => $meter['Unit'],
'source' => $source,
'time' => Carbon::parse($raw['t'])->toIso8601ZuluString(),
'delta' => $raw['d'],
]));
}
// Insert into TimescaleDB cut
}
return response()->json(['message' => $ok . " Raws has been inserted,\n " . $nok . " Failed"], 200);
}
我第一次调用它时,我有一个包含 3744 个元素的主体。
每个元素推入数组大约需要 5-6 毫秒,因此,大约 6 x 3744 / 1000 = 22 秒。
但我的第二篇文章有 26930 个元素。现在,每个array_push
大约需要 52 毫秒,所以 52 * 26930 / 1000 = 23 分钟。路长。
应该总是相同的array_push
,与 body 中有多少行无关?
为什么花费的时间array_push
与大小成正比$chunkedRaws
???
解决方案
您可以尝试在外部声明该对象。如上所述,您可以停止使用 array_push
...
$raw = new \App\Models\Raw([
'operation_id' => $meter['OperationID'],
'meter_id' => $meter['ID'],
'conso_prod' => $meter['ConsoProd'],
'timestep' => $meter['Timestep'],
'unit' => $meter['Unit'],
'source' => $source,
]);
foreach ($chunkedRaws as $chunkNumber => $raws) {
$chunkTime = Carbon::now();
$rawsToInsert = [];
foreach ($raws as $k => $raw) {
$rawTime = Carbon::now();
// Here I'm assuming you have setter in your Raw object
$raw->setTime(Carbon::parse($raw['t'])->toIso8601ZuluString());
$raw->setDelta($raw['d']);
$rawsToInsert[] = $raw;
}
// Insert into TimescaleDB cut
}
...
推荐阅读
- bash - 启动脚本以启动分离的屏幕并在其中运行 bash 脚本
- angular - 在 Angular 的对话框组件中使用 [mat-dialog-close] 指令
- java - < 字符的 SaxParser 问题
- c# - C# UWP MVVM 在另一个视图中注入一个视图
- python - 没有名为“asgiref.base_layer”的模块
- java - 如何在单元测试中使用准备好的语句模拟 jdbctemplate
- c# - 美国与英国日期格式的问题(Kendo/MVC/SQL)
- python - 无法使用 get_att 将 IAM 策略添加到 Glue Crawler
- javascript - 删除类并将其添加到 localStorage
- cassandra - 我们在哪里可以在 Datastax java-driver 中指定 THROW_ON_OVERLOADED=true?