У меня есть эта функция, которая вычисляет балансовую стоимость основных средств с использованием данных из таблицы амортизации, Ii отлично работает на локальном хосте, но когда я пытался продолжить производство, я получаю `` тайм-аут запроса '' после долгой загрузки, я Думаю, я испортил цикл или что-то в этом роде, и будет здорово, если кто-нибудь предложит оптимизацию кода или взлом, чтобы сделать эту функцию быстрее.
Я попытался ограничить количество записей в цикле, и это сработало, но, к сожалению, мне нужно обработать более 20 000 данных.
$cat = null;
$total_a = null;
$assets = $this->Depreciation->get_all();
if (!empty($assets)) {
foreach ($assets as $asset) {
$cost = $asset->cost + $asset->add_cost + $asset->adj_cost;
$salve = $asset->salvage_value;
$life = $asset->life;
$life_t = 0;
$counter = 0;
$date1 = date('Y-12-31');
$date2 = $asset->in_service;
$diff = abs(strtotime($date2) - strtotime($date1));
$years = floor($diff / (365 * 60 * 60 * 24));
$months = floor(($diff - $years * 365 * 60 * 60 * 24) / (30 * 60 * 60 * 24));
$in_service_d = date('Y-12-31');
if ($asset->rev > 0) {
$cost = $asset->rev;
}
$dep1 = ($cost - $salve) / $life * ($months / 12);
$dep = ($cost - $salve) / $life;
$total = 0;
$year = 1;
for (; $cost > $salve;) {
if ($year == 1 && $months < 12) {
$life_t++;
$year++;
$cost = $cost - $dep1;
$counter++;
$total = $dep1 + $total;
if ($in_service_d == date('Y-12-31')){
$total_a = $total_a + $cost;
}
$in_service_d = date('Y-12-31', strtotime("+12 months", strtotime($in_service_d)));
} elseif ($year != 1) {
$life_t++;
if ($life_t > $life) {
$dep = $dep - $dep1;
}
$cost = $cost - $dep;
$counter++;
$total = $dep + $total;
if ($in_service_d == date('Y-12-31')){
$total_a = $total_a + $cost;
}
$in_service_d = date('Y-12-31', strtotime("+12 months", strtotime($in_service_d)));
}
}
}
}
return $total_a;
Один совет: логика вашей программы слишком сложна для тестирования. Я бы порекомендовал вам разбить вашу логику на более мелкие функции и протестировать каждую из них. Таким образом у вас будет больше уверенности в том, что делает каждая часть.
Стоимость снижается $cost = $cost - $dep1; или $cost = $cost - $dep; в зависимости от «$ Year» на каждой итерации.
Подозреваю, что проблема в цикле, но я не могу понять, как этот цикл занимает так много времени всего на 21 запись.
Можно ли получить данные для примера $asset? Трудно понять логику вашей программы.
Кроме того, это помогает, если вы используете var_dump для некоторых ключевых переменных в вашем цикле. Обычно это помогает отследить причину проблемы. Бьюсь об заклад, $cost не так, как вы ожидали.
Вы имеете в виду так: unsee.cc/ffb26821
Я попробовал одно из ваших данных и запустил его 20000 раз. И это заканчивается за 8 секунд. Так что я не думаю, что это безумно долгое вычисление. Я думаю, что, вероятно, есть одна конкретная строка, которая вызвала проблему. Я бы посоветовал вам поместить var_dump($asset->a_id); в начало вашего цикла foreach. Затем запустите и посмотрите, какой актив вас застрял.
Нашел одну логическую проблему. Цикл for будет продолжаться вечно, если $months больше 12. Не уверен, действительно ли это происходит, ты.






Ваш друг - функция set_time_limit().
У меня был аналогичный сценарий экспорта отформатированного файла Excel из большой базы данных. У сценария всегда не хватало времени, если он превышал 1000 строк.
В разделе моей логики loop я установил следующее:
set_time_limit(30);
Что увеличило бы разрешенное время для бега еще на 30 секунд с этого момента.
У меня заканчивается время всего с 21 записью. Когда вы добавляете эту функцию, как насчет пользовательского опыта? Я думаю, что пользователю придется подождать некоторое время для завершения операции, и, к сожалению, эта функция запускается сразу после входа в мое приложение.
Мое требование заключалось в сценарии загрузки, поэтому от пользователя было четкое предупреждение, что им придется немного подождать. Вы уверены, что ваш скрипт завершится после 21 записи? Но на локальном хосте он работает нормально? Какой тайм-аут скрипта на сервере? И каков размер полного набора данных, который необходимо обработать? Может быть проблема с объемом памяти?
Если не задействованы никакие операции с базой данных, 20 000 строк не являются особенно большим набором данных. Я еще не изучил всю логику программы, но цикл выполняется до тех пор, пока
$costбольше, чем$salve. Вы уверены, что либо$costвыходит из строя, либо$salveподнимается на всех итерациях?