Skip to content

Commit

Permalink
Cache generated date range periods.
Browse files Browse the repository at this point in the history
This is a bit experimental and I need to see whether any test will
fail. It takes a long time to generate subperiods for period=range.
Eg requesting date=2015-01-04,2015-02-02&module=Referrers&action=getSearchEngines&period=range
took about 700ms for each request of 1500ms in total. It now takes
only 40ms which means it is 30-40% faster. With the other optimizations
the request in total does now only take 700-800ms instead of 1500ms.
  • Loading branch information
tsteur committed Feb 2, 2015
1 parent e349e24 commit 832ecfb
Showing 1 changed file with 62 additions and 0 deletions.
62 changes: 62 additions & 0 deletions core/Period/Range.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
namespace Piwik\Period;

use Exception;
use Piwik\Cache;
use Piwik\Common;
use Piwik\Date;
use Piwik\Period;
Expand All @@ -32,6 +33,11 @@ class Range extends Period
protected $label = 'range';
protected $today;

/**
* @var null|Date
*/
protected $defaultEndDate;

/**
* Constructor.
*
Expand All @@ -56,6 +62,41 @@ public function __construct($strPeriod, $strDate, $timezone = 'UTC', $today = fa
$this->today = $today;
}

private function getCache()
{
return Cache::getTransientCache();
}

private function getCacheId()
{
$end = '';
if ($this->defaultEndDate) {
$end = $this->defaultEndDate->getTimestamp();
}

$today = $this->today->getTimestamp();

return 'range' . $this->strPeriod . $this->strDate . $this->timezone . $end . $today;
}

private function loadAllFromCache()
{
$range = $this->getCache()->fetch($this->getCacheId());

if (!empty($range)) {
foreach ($range as $key => $val) {
$this->$key = $val;
}
}
}

private function cacheAll()
{
$props = get_object_vars($this);

$this->getCache()->save($this->getCacheId(), $props);
}

/**
* Returns the current period as a localized short string.
*
Expand Down Expand Up @@ -156,6 +197,12 @@ protected function generate()
return;
}

$this->loadAllFromCache();

if ($this->subperiodsProcessed) {
return;
}

parent::generate();

if (preg_match('/(last|previous)([0-9]*)/', $this->strDate, $regs)) {
Expand Down Expand Up @@ -214,13 +261,15 @@ protected function generate()

if ($this->strPeriod != 'range') {
$this->fillArraySubPeriods($startDate, $endDate, $this->strPeriod);
$this->cacheAll();
return;
}

$this->processOptimalSubperiods($startDate, $endDate);
// When period=range, we want End Date to be the actual specified end date,
// rather than the end of the month / week / whatever is used for processing this range
$this->endDate = $endDate;
$this->cacheAll();
}

/**
Expand Down Expand Up @@ -462,4 +511,17 @@ private function isEndOfWeekLaterThanEndDate($endDate, $endOfWeek)

return $isEndOfWeekLaterThanEndDate;
}

/**
* Returns the date range string comprising two dates
*
* @return string eg, `'2012-01-01,2012-01-31'`.
*/
public function getRangeString()
{
$dateStart = $this->getDateStart();
$dateEnd = $this->getDateEnd();

return $dateStart->toString("Y-m-d") . "," . $dateEnd->toString("Y-m-d");
}
}

2 comments on commit 832ecfb

@tsteur
Copy link
Member Author

@tsteur tsteur commented on 832ecfb Feb 2, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On our demo test server this call does now take only about 0.75seconds instead of 1.7

index.php?date=2015-01-04,2015-02-02&module=Referrers&action=getSearchEngines&widget=1&isFooterExpandedInDashboard=true&flat=1&idSite=1&period=range

@mattab
Copy link
Member

@mattab mattab commented on 832ecfb Feb 9, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice performance improvement, interesting!

Please sign in to comment.