Simple but major performance fixes

In particular for level 1 scoring & image loading.
Now that we have a fuller db of images we can be stricker in the range we select.
This commit is contained in:
Ruben van de Ven 2018-11-14 19:00:15 +01:00
parent 7a1dda439e
commit 8b0459c0f6
3 changed files with 85 additions and 65 deletions

View file

@ -138,7 +138,8 @@ class InterfaceControllerProvider implements ControllerProviderInterface
$hit = $hitRepo->getClosestHitWithImage($emotion, $i);
$img = "data:image/x-icon;base64,".$hit->getFeatureImgAsString($feature);
$score = $hit->getEmotions()->getEmotionScore($emotion);
$percentage = sprintf("%.0f %%",$score);
// $percentage = sprintf("%.0f %%",$score);
$percentage = sprintf("%.0f",$score); // use :after to append % character
$blocks[$position] = [
'hit_id' => $hit->getId(),
'img_data' => $img,

View file

@ -17,6 +17,7 @@ use Doctrine\Common\Collections\ArrayCollection;
* @ORM\Index(name="imgJoy", columns={"hasImage", "joy"}),
* @ORM\Index(name="imgSadness", columns={"hasImage", "sadness"}),
* @ORM\Index(name="imgSurprise", columns={"hasImage", "surprise"}),
* @ORM\Index(name="targetScore", columns={"target", "score"}),
* })
* @ORM\Entity
* @ORM\Entity(repositoryClass="EmotionHero\Models\HitRepository")

View file

@ -12,6 +12,8 @@ class HitRepository extends EntityRepository
* @return Hit The hit that is considered better than the given one (used for hints)
*/
public function getBetterHit(Hit $hit) {
$targets = $this->getTargetSetForTarget($hit->getTarget());
if(count($targets) > 1) {
// we want only the slightly better hit...
$query = $this->_em->createQuery(
"SELECT h, SUM(h.score) as HIDDEN totalScore FROM ".Hit::class." h WHERE h.target IN (:targets) GROUP BY h.game HAVING totalScore > :score ORDER BY totalScore DESC"
@ -19,9 +21,21 @@ class HitRepository extends EntityRepository
->setMaxResults(1)
->setParameters([
'score' => $this->getTotalScoreForHit($hit),
'targets' => $this->getTargetSetForTarget($hit->getTarget()),
'targets' => $targets,
]);
$betterHit = $query->getOneOrNullResult();
} else { // run a faster query if there's just on target (no grouping needed)
// we want only the slightly better hit...
$query = $this->_em->createQuery(
"SELECT h FROM ".Hit::class." h WHERE h.target = :target AND h.score > :score ORDER BY h.score DESC"
)
->setMaxResults(1)
->setParameters([
'score' => $this->getTotalScoreForHit($hit),
'target' => array_shift($targets),
]);
$betterHit = $query->getOneOrNullResult();
}
return $betterHit;
}
@ -38,12 +52,16 @@ class HitRepository extends EntityRepository
throw new \Exception("Invalid emotion!");
}
$scoreMin = $score < 0.1 ? 0 : $score - 0.3;
$scoreMax = $score < 0.1 ? 0 : $score + 0.3;
$query = $this->_em->createQuery(
// add BETWEEN so we can use _some_ keying to improve performance.
"SELECT h, ABS(:score - h.emotions.$emotionField) as HIDDEN distance, RAND() AS HIDDEN lala FROM ".Hit::class." h WHERE h.hasImage = :has AND h.emotions.$emotionField BETWEEN :score - 2 AND :score + 2 ORDER BY distance ASC, lala"
"SELECT h, ABS(:score - h.emotions.$emotionField) as HIDDEN distance, RAND() AS HIDDEN lala FROM ".Hit::class." h WHERE h.hasImage = :has AND h.emotions.$emotionField BETWEEN :score_min AND :score_max ORDER BY distance ASC, lala"
)
->setParameters([
'score' => $score,
'score_min' => $scoreMin,
'score_max' => $scoreMax,
'has' => true,
])
->setMaxResults(1);