Symfony,创建新对象慢

时间:2015-06-17 09:33:10

标签: php symfony doctrine-orm

我需要编写一个foreach循环,用户可以使用doctrine订阅并插入到数据库中。我的代码:

$i=0;
$batchSize=20;

foreach ($members as $member) {
    $subscription = new Subscription($company, $user);
    $entityManager->persist($subscription);
    // debug
    $i++;
    error_log($i);

    if ($i % $batchSize === 0) {
        $entityManager->flush();
        $entityManager->clear();
    }
}

这段代码真的很慢。对于大约100个用户,此代码需要几分钟才能执行。这应该快得多吗?

当我删除对象创建(以及setMember和entityManager行)时,执行此代码的时间不到一秒。

我做错了什么?

更新:实体代码 由于代码机密,我改变了一些变量。如果有任何代码是错误的,那是因为我所做的快速更改,所以我可以在这里发布我的问题。

class Subscription implements \JsonSerializable
{

    protected $id;
    protected $company;
    protected $user;
    private $created_on;
    private $blocked;
    private $attributes;

    public function __construct(Company $company, User $user)
    {
        $this->company = $company;
        $this->user = $user;
        $this->created_on = new \DateTime();
        $this->blocked = false;

        $this->attributes = new AttributeCollection();

        $this->setDefaultAttributes();
    }

    public function jsonSerialize() {
        return array(
            'id' => $this->id,
            'user' => $this->user,
            'blocked' => $this->blocked,
            'created_on' => $this->created_on->format('Y-m-d H:i:s')
        );
    }
    // due to company secrets variables have been changed to a,b,c,d,e,f
    public function setDefaultAttributes()
    {
        if (null == $this->attributes)
            $this->attributes = new AttributeCollection();
        $this->attributes->addAttribute(new Attribute('a'));
        $this->attributes->addAttribute(new Attribute('b'));
        $this->attributes->addAttribute(new Attribute('c'));
        $this->attributes->addAttribute(new Attribute('d'));
        $this->attributes->addAttribute(new Attribute('e'));
        $this->attributes->addAttribute(new Attribute('f'));
    }

    public function getId()
    {
        return $this->id;
    }

    public function setUser(User $user = null)
    {
        $this->user = $user;

        return $this;
    }

    public function getUser()
    {
        return $this->user;
    }

    public function setCompany(Company $company = null)
    {
        $this->company = $company;
        return $this;
    }

    public function getCompany()
    {
        return $this->company;
    }

    public function getCreatedOn()
    {
        return $this->created_on;
    }

    public function setBlocked($blocked)
    {
        $this->blocked = $blocked;

        return $this;
    }

    public function getBlocked()
    {
        return $this->blocked;
    }

    public function setAttributes(AttributeCollection $attributes = null)
    {
        $this->attributes = $attributes;
        return $this;
    }

    public function getAttributes()
    {
        return $this->attributes;
    }

}

上面的Subscription类中使用的AttributeCollection类:

class AttributeCollection
{

    protected $id;
    protected $attributes;

    public function __construct()
    {
        $this->attributes = new ArrayCollection();
    }

    public function removeDefaults()
    {
        foreach ($this->attributes as $attribute)
            if ($attribute->isSystemDefault())
                $this->removeAttribute($attribute);
    }

    public function clearDefaults()
    {
        foreach ($this->attributes as $attribute)
            $attribute->setSystemDefault(false);
    }

    public function getAttributes()
    {
        return $this->attributes;
    }

    public function addAttribute(Attribute $attribute)
    {
        if (!$this->findAttributeByName($attribute->getName()))
            $this->attributes[] = $attribute;
    }

    public function removeAttribute(Attribute $attribute)
    {
        $this->attributes->removeElement($attribute);
    }

    public function findAttributeByName($name)
    {
        foreach ($this->attributes as $attribute)
            if ($attribute->getName() == $name)
                return $attribute;
        return;
    }

    public function get($name)
    {
        $attribute = $this->findAttributeByName($name);
        if ($attribute)
            return $attribute->getValue();
        return;
    }

    public function getAll()
    {
        return $this->attributes->toArray();
    }

}

2 个答案:

答案 0 :(得分:1)

事实证明,通过构造函数传递这些模型会导致问题。

我改变了我的代码:

class Subscription {
    ...
    public function __construct($Company == null, $member == null) {
        ...
    }
}

在我的foreach循环中:

$subscription = new Subscription();
$subscription->setCompany($company);
$subscription->setMember($member);

这样一切都顺利进行并且符合预期。我不知道为什么构造函数会减慢一切。但显然确实如此。

答案 1 :(得分:0)

对这样的小实体使用这么小的$batchSize是不理想的。

这种持久性的方式在文档中提供,作为如何优化内存和连接加载的示例,而不是整个脚本的速度。

如果您在$i$batchSize上删除这些检查,则会更快。

foreach ($members as $member) {
    $subscription = new Subscription();
    $subscription->setMember($member);
    $entityManager->persist($subscription);
}
$entityManager->flush();

另请注意,在dev-env中,debug选项设置为enabled,并且对数据库的所有查询都记录在文件中。这也浪费时间。