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); $hit = $hitRepo->getClosestHitWithImage($emotion, $i);
$img = "data:image/x-icon;base64,".$hit->getFeatureImgAsString($feature); $img = "data:image/x-icon;base64,".$hit->getFeatureImgAsString($feature);
$score = $hit->getEmotions()->getEmotionScore($emotion); $score = $hit->getEmotions()->getEmotionScore($emotion);
$percentage = sprintf("%.0f %%",$score); // $percentage = sprintf("%.0f %%",$score);
$percentage = sprintf("%.0f",$score); // use :after to append % character
$blocks[$position] = [ $blocks[$position] = [
'hit_id' => $hit->getId(), 'hit_id' => $hit->getId(),
'img_data' => $img, 'img_data' => $img,

View file

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

View file

@ -12,16 +12,30 @@ class HitRepository extends EntityRepository
* @return Hit The hit that is considered better than the given one (used for hints) * @return Hit The hit that is considered better than the given one (used for hints)
*/ */
public function getBetterHit(Hit $hit) { public function getBetterHit(Hit $hit) {
// we want only the slightly better hit... $targets = $this->getTargetSetForTarget($hit->getTarget());
$query = $this->_em->createQuery( if(count($targets) > 1) {
"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" // we want only the slightly better hit...
) $query = $this->_em->createQuery(
->setMaxResults(1) "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"
->setParameters([ )
'score' => $this->getTotalScoreForHit($hit), ->setMaxResults(1)
'targets' => $this->getTargetSetForTarget($hit->getTarget()), ->setParameters([
]); 'score' => $this->getTotalScoreForHit($hit),
$betterHit = $query->getOneOrNullResult(); '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; return $betterHit;
} }
@ -38,12 +52,16 @@ class HitRepository extends EntityRepository
throw new \Exception("Invalid emotion!"); 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( $query = $this->_em->createQuery(
// add BETWEEN so we can use _some_ keying to improve performance. // 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([ ->setParameters([
'score' => $score, 'score' => $score,
'score_min' => $scoreMin,
'score_max' => $scoreMax,
'has' => true, 'has' => true,
]) ])
->setMaxResults(1); ->setMaxResults(1);