i am creating a fitness app that has a structure:
User has one Program, Program has many workouts, Workouts has many Exercises (M:M) and Workouts has many Supersets, Supersets has many Exercises(M:M).
So i have the algorithm that creates Program that has 9 workouts and every workout has 6-8 exercises, for every exercise I find a suitable one from DB and save it associated with the workout. So in general i create one program, 9 workouts and 54-72 exercises.
However, i takes 20-25 seconds for the whole process. It is too much. I tried using raw, attributes options.
Here is the algorithm for creating one workout. I check here different options for exercises, but that should not slow the process much. You don't need to understand what are the fields in the models. I would appreciate any help, thanks!!!
public static async generateWorkout(body: WorkoutRequestApi, currentDay: number, workoutCounter: number) {
let existing: string[] = [];
let exercise: ExercisesModels | null;
const workoutId: string = randomUUID();
await Workout.create({
uuid: workoutId,
isFinished: false,
programId: body.progId,
type: body.programOptions.types[workoutCounter]
})
await Superset.create({uuid: workoutId})
for (let i = 0; i < body.programOptions.workouts[currentDay].length; i ) {
console.log("DAY: " currentDay " I: " i)
const currentExerciseModel = body.programOptions.workouts[currentDay][i];
let unique: boolean = false;
console.log(currentExerciseModel)
if (currentExerciseModel.isSuperset) {
while (!unique) {
const firstExercise: ExercisesModels | null = await ExerciseUtil.findWorkoutExercise(currentExerciseModel, currentExerciseModel.hasPriority ? true : false)
const secondExercise: ExercisesModels | null = await ExerciseUtil.findFixedExercise(body.programOptions.workouts[currentDay][i 1])
if (firstExercise && secondExercise) {
if (!existing.includes(firstExercise.uuid)) {
unique = true
existing.push(firstExercise.uuid)
existing.push(secondExercise.uuid)
console.log("INSERTING " firstExercise.uuid " and " secondExercise.uuid)
exercise = await this.modelToExercises(firstExercise, {
reps: currentExerciseModel.reps,
sets: currentExerciseModel.sets,
order: i
}
)
console.log(exercise)
await SupersetExercise.create({
ExerciseUuid: exercise.uuid,
SupersetUuid: workoutId
})
exercise = await this.modelToExercises(secondExercise, {
reps: currentExerciseModel.reps,
sets: currentExerciseModel.sets,
order: i 1
}
)
await SupersetExercise.create({
ExerciseUuid: exercise.uuid,
SupersetUuid: workoutId
})
}
}
}
i ;
if (i >= body.programOptions.workouts[currentDay].length)
break
} else {
if (currentExerciseModel.isFixed === true) {
console.log("FIXED EXERCISE")
exercise = await ExerciseUtil.findFixedExercise(currentExerciseModel);
if (exercise) {
console.log("FOUND FIXED" exercise.name)
exercise = await this.modelToExercises(exercise, {
reps: currentExerciseModel.reps,
sets: currentExerciseModel.sets,
order: i
}
)
try {
await WorkoutExercise.create({
WorkoutUuid: workoutId,
ExerciseUuid: exercise.uuid
});
} catch (e) {
console.log(<Error>e)
}
}
} else {
while (!unique) {
exercise = await ExerciseUtil.findWorkoutExercise(currentExerciseModel, i <= 2)
if (exercise) {
if (!existing.includes(exercise.uuid)) {
unique = true
existing.push(exercise.uuid)
exercise = await this.modelToExercises(exercise, {
reps: currentExerciseModel.reps,
sets: currentExerciseModel.sets,
order: i
})
try {
await WorkoutExercise.create({
WorkoutUuid: workoutId,
ExerciseUuid: exercise.uuid
});
} catch (e) {
console.log(<Error>e)
}
}
}
}
}
}
}
CodePudding user response:
At chance, your code hits the database 3 times for every while interaction. Doing some basic math that would take hopefully 300ms (100ms for each git) and for every 3 records you'd get about 1 sec wait.
My recommendation would be to obtain those records before the white and then read them in the memory. I'm no specialist in Superset but this is basic database IO.
Every time you hit the database you can count as at least 100ms delay average, sometimes even more.
I know that at first it wouldn't seem to make sense since you'd spare memory in this case. If you can filter only the records that you'll need to that array. Someone once told me: "tuning is much more art than logic". LOL.
A single request with all the info that you'll need will tame like 120ms (more than a single one) but it will avoid other 1000 requests along the way.