【发布时间】:2018-01-05 05:45:36
【问题描述】:
我目前正面临一场噩梦。我的数据库几乎只有 400 条记录,问题是我的 PHP 代码正在生成图像滑块,因此代码几乎需要 60 秒 才能执行 >400条记录,时间太长了,没有人能忍受等待这么长时间。 我真的很担心,因为我不确定可以做些什么来让它更快,但据我所知,使用 foreach 循环而不是 for 循环可以让事情变得更快,但我想知道你们是否可以取悦为我提供解决方案。
它是 Symfony 站点内的部分模板,它呈现图像滑块并从数据库中获取每个图像的滑块。但我并不担心 SQL 查询,因为执行所有查询以获取这些滑块图像最多只需要 3 到 4 秒,但是生成滑块的这段代码需要很多时间在大多数情况下,更多的时间几乎是 60 多秒,这对于任何人来说都需要等待太多时间。
如果你们可以为我提供优化的代码以获得最佳性能,我将不胜感激。
<?php if (count($locations) > 0): ?>
<?php foreach ($locations as $location): ?>
<?php if ($location->PhotoFiles->count()): ?>
<li class="item" data-location-id="<?php echo $location->id ?>">
<div class="searchItemSlider">
<?php $limit = ($location->PhotoFiles->count() >= 10 ? 10 : $location->PhotoFiles->count()); ?>
<?php for ($i = 1; $i < ($limit + 1); $i++): ?>
<?php $photo = $location->findPhotoIndex($i); ?>
<?php //if (1): ?>
<?php if ($photo && $thumb = $photo->getThumbnailByType(ThumbnailTable::THUMB_520_392)): ?>
<div class="searchItem">
<figure>
<?php if (file_exists($thumb->getFullFilesystemPath())): ?>
<?php //if (1 == 2): ?>
<div class="thumb-img">
<img class="lazyOwl" src="<?php echo $thumb->getFullWebPath() ?>" />
</div>
<?php else: ?>
<div class="thumb-img">
<img class="lazyOwl" src="/images/newfrontend/categories/no_venue.jpg" />
</div>
<?php endif; ?>
<figcaption>
<a href="<?= url_for("@venue_details?id=" . $location->id) ?>" title="<?php echo $location->venue_name; ?>"><?php echo $location->venue_name; ?></a>
<br />
</figcaption>
<?php $districtName = (strlen($location->venue_area)) ? $location->venue_area : $location->getGeoLocationDistrictName();
if (strlen($districtName)): ?>
<div class="district_name"><a href="<?= url_for("@venue_details?id=" . $location->id) ?>" title="<?php echo $location->venue_name; ?>"><?php echo $districtName ?></a></div>
<?php endif; ?>
</figure>
<p><?php echo substr(strip_tags(html_entity_decode($location->description)), 0, 100) ?></p>
<span class="eye"><a href="<?= url_for("@venue_details?id=" . $location->id) ?>" title="<?php echo $location->venue_name; ?>"><img src="/images/newfrontend/icons/eye-icon.png"/></a></span>
<div class="links">
<a href="<?php echo url_for('@venue_share?id=' . $location->id) ?>" class="arrow share_links" data-toggle="tooltip" title="Share this venue"> </a>
<?php if (!$sf_user->locationInWishlist($location->id)): ?>
<a href="<?php echo url_for('@wishlist_addtowishlistajaxraw') ?>" data-attr-venue-id="<?php echo $location->id ?>" class="pin add_to_wishlist" data-toggle="tooltip" title="Add to wishlist"> </a>
<?php else: ?>
<a href="javascript:void(0)" class="added-to-wishlist"> </a>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<?php endfor; ?>
</div>
</li>
<?php else: ?>
<li class="item" data-location-id="<?php echo $location->id ?>">
<div class="searchItemSlider">
<div class="searchItem">
<figure>
<div class="thumb-img">
<img class="lazyOwl" src="/images/newfrontend/categories/no_venue.jpg" />
</div>
<figcaption>
<a href="<?= url_for("@venue_details?id=" . $location->id) ?>" title="<?php echo $location->venue_name; ?>"><?php echo $location->venue_name; ?></a>
<br />
</figcaption>
<?php $districtName = (strlen($location->venue_area)) ? $location->venue_area : $location->getGeoLocationDistrictName();
if (strlen($districtName)):
?>
<div class="district_name"><a href="<?= url_for("@venue_details?id=" . $location->id) ?>" title="<?php echo $location->venue_name; ?>"><?php echo $districtName ?></a></div>
<?php endif; ?>
</figure>
<p><?php echo substr(strip_tags(html_entity_decode($location->description)), 0, 100) ?></p>
<span class="eye"><a href="<?= url_for("@venue_details?id=" . $location->id) ?>" title="<?php echo $location->venue_name; ?>"><img src="/images/newfrontend/icons/eye-icon.png"/></a></span>
<div class="links">
<a href="<?php echo url_for('@venue_share?id=' . $location->id) ?>" class="arrow share_links" title="Share this venue"> </a>
<?php if (!$sf_user->locationInWishlist($location->id)): ?>
<a href="<?php echo url_for('@wishlist_addtowishlistajaxraw') ?>" data-attr-venue-id="<?php echo $location->id ?>" class="pin add_to_wishlist" data-toggle="tooltip" title="Add to wishlist"> </a>
<?php else: ?>
<a href="javascript:void(0)" class="added-to-wishlist"> </a>
<?php endif; ?>
</div>
</div>
</div>
</li>
<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>
更新:
位置: /lib/model/doctrine/PhotoFile.class.php
/**
* Returns the first thumbnail of a certain type
* or false if no thumbnail matches
*
* @param const $type The type of thumbnail, from the ThumbnailTable::THUMB_* constants
* @return bool|Thumbnail
*/
public function getThumbnailByType($type) {
foreach ($this->Thumbnails as $t) {
if ($t->thumb_type == $type) {
return $t;
}
}
return false;
}
位置: /lib/model/doctrine/Location.class.php
/**
* Geocoder: get district name (administrative county)
*
* @return string
*/
public function getDistrictName()
{
return ($this->hasGeocode() ? $this->getGeocode()->district_name : null);
}
public function getGeoLocationDistrictName()
{
$districtName = '';
if($this->getGeocoded()->count() > 0)
{
if($this->getGeocoded()->getFirst()->getGeolocationPostcode()->count() > 0)
{
if($this->getGeocoded()->getFirst()->getGeolocationPostcode()->getFirst()->getGeolocationDistrict()->count() > 0)
{
$districtName = $this->getGeocoded()->getFirst()->getGeolocationPostcode()->getFirst()->getGeolocationDistrict()->getFirst()->getName();
}
}
}
return $districtName;
}
/**
* Gets the geocode data for this location.
* We store it locally so we don't need to keep querying for it.
*
* @return boolean|PcawCodes $pcawCode
*/
public function getGeocode()
{
if ($this->Geocoded->count())
{
return $this->Geocoded->getFirst();
}
if (!strlen($this->address_postcode))
{
// No postcode to geocode
return false;
}
$geocode = new JointGeocoder();
try
{
/* @var $result PcawCodes */
$result = $geocode->geocode("", $this->address_postcode);
// Add the postcode also to the GeolocationPostcode table
if($result) Doctrine::getTable('GeolocationPostcode')->addPostcodeIfMissing($result);
}
catch (Exception $e)
{
// Some problem occurred geocoding, return false
return false;
}
return $result;
}
【问题讨论】:
-
你怎么知道,你有没有对你的代码进行基准测试,看看它在哪里花费时间?
-
only takes about 3 to 4 seconds at most to execute all queries人的平均注意力持续时间约为 6 秒,我尝试在此范围内加载页面。 -
你也可以避免重复计算,比如
$location->PhotoFiles->count()被使用了3次,你可以将它存储在一个变量中并使用它 -
你可以从我正在编写的
Evolution框架中借用我的基准测试类(是的,我正在编写自己的框架,无耻的插件)这里github.com/ArtisticPhoenix/Evo/blob/master/Evo/Benchmark.php -
你像这样使用它,
$mark = Benchmark::getInstance()->mark('A'); ..other code ... echo Benchmark::getInstance()->format($mark);它会说从开始到结束需要多长时间。
标签: php performance symfony processing-efficiency