【发布时间】:2021-11-29 17:48:11
【问题描述】:
我似乎无法理解为什么这个迭代如此缓慢,所以我希望有人能帮助我。 此功能用于在特定时间安排一些操作,并循环机器人列表(将执行操作)和组列表(操作的目标) 完成 1300 个组和 50 个机器人大约需要 10 分钟。提前谢谢您,这非常重要!
for (let groupIndex = 0; groupIndex < groups.length; groupIndex++) {
let group = groups[groupIndex];
if (!answers.find(a => a.GroupId == group.Id))
continue;
for (let botIndex = 0; botIndex < bots.length; botIndex++) {
var bot = bots[botIndex];
if (bot.Disabled)
continue;
var bot_joined_groups = bots_joined_groups.find(j => j.Id == bot.Id);
if (bot_joined_groups) {
bot_joined_groups = bot_joined_groups.Groups;
if (bot_joined_groups.find(j => j.GroupId == group.Id))
continue;
} else
bot_joined_groups = [];
var day = 60 * 60 * 24 * 1000;
var today = new Date();
if (today < (new Date(bot.WarmingUpEndAt)))
today = new Date(bot.WarmingUpEndAt);
else if (Math.floor((Date.parse(today) - Date.parse(bot.LimitAt)) / 86400000) < 7) {
today = new Date(bot.LimitAt);
today.setTime(today.getTime() + day * 7);
}
var scheduled_joins = scheduled_joins_total.filter(j => j.BotId == bot.Id);
var schedule_date = new Date();
if (scheduled_joins.length) {
schedule_date = scheduled_joins.find(j => {
let at = new Date(j.At);
let count = scheduled_joins.filter(c => at.getDate() === new Date(c.At).getDate() && at.getMonth() === new Date(c.At).getMonth() && at.getFullYear() === new Date(c.At).getFullYear()).length;
if (count < 10)
return true;
});
if (schedule_date)
schedule_date = new Date(schedule_date.At);
else {
schedule_date = new Date(scheduled_joins[scheduled_joins.length - 1].At);
schedule_date = new Date(schedule_date.getTime() + day);
}
} else
schedule_date = today;
let min_hours = 0;
let min_minutes = 0;
if (today.getDate() == schedule_date.getDate() && today.getMonth() == schedule_date.getMonth() && today.getFullYear() == schedule_date.getFullYear()) {
var joined_today_count = bot_joined_groups.filter(c => today.getDate() === new Date(c.JoinedAt).getDate() && today.getMonth() === new Date(c.JoinedAt).getMonth() && today.getFullYear() === new Date(c.JoinedAt).getFullYear()).length;
if (joined_today_count >= 10) {
schedule_date = new Date(scheduled_joins_total.length ? (new Date(scheduled_joins_total[scheduled_joins_total.length - 1].At)).getTime() : today.getTime() + day);
min_hours = 0;
min_minutes = 0;
}
else {
if (today.getHours() == 23) {
schedule_date = new Date(scheduled_joins_total.length ? (new Date(scheduled_joins_total[scheduled_joins_total.length - 1].At)).getTime() : today.getTime() + day);
min_hours = 0;
min_minutes = 0;
}
else {
if (schedule_date.getHours() <= today.getHours())
min_hours = today.getHours() + 1;
joined_today_count++;
}
}
}
schedule_date.setHours(Math.random() * (23 - min_hours + 1) + min_hours);
schedule_date.setMinutes(Math.random() * 59 + min_minutes);
schedule_date.setSeconds(Math.random() * 59);
var today_joins_count = 0;
do {
today_joins_count = scheduled_joins_total.filter(c => schedule_date.getDate() === new Date(c.At).getDate() && schedule_date.getMonth() === new Date(c.At).getMonth() && schedule_date.getFullYear() === new Date(c.At).getFullYear() && c.GroupId === group.Id).length;
if (today_joins_count)
schedule_date.setTime(schedule_date.getTime() + day);
} while (today_joins_count);
scheduled_joins_total.push({
BotId: bot.Id,
GroupId: group.Id,
At: schedule_date
});
values.push(`(${bot.Id}, ${group.Id}, to_timestamp(${schedule_date.getTime() / 1000.0}))`);
}
}
【问题讨论】:
-
真的,您应该使用计时器和 console.logging 基准来查找最慢的行,并研究替代方法。对于初学者,请查看nikitahl.com/how-to-find-an-item-in-a-javascript-array
-
如果你可以使用对象或
Map来查找id,而不是多次调用find,性能应该会大大提高。 -
我建议更多的散列和更多的缓存。
-
在每个循环中都会发生大量一次性声明。有很多改进的机会。
标签: javascript performance loops