QQuickSpinBox: create JS callbacks lazily

Calling QJSEngine::evaluate() is a heavy operation. Only one of them,
namely textFromValue, is used from QML, so there's a good chance that
valueFromText doesn't need to be evaluated at component creation time.
This change postpones the initial evaluation to the point where either
callback is requested.

Before:

    RESULT : tst_CreationTime::controls():"SpinBox":
         0.53 msecs per iteration (total: 68, iterations: 128)

After:

    RESULT : tst_CreationTime::controls():"SpinBox":
         0.39 msecs per iteration (total: 51, iterations: 128)

Change-Id: I1730dc4024d0a556ca2da765ac3c52ba8a29f743
Reviewed-by: Mitch Curtis <mitch.curtis@theqtcompany.com>
This commit is contained in:
J-P Nurmi 2016-01-29 09:46:25 +01:00 committed by Simon Hausmann
parent 584b768cd0
commit 1f146d982b
2 changed files with 12 additions and 16 deletions

View File

@ -116,8 +116,8 @@ public:
QQuickSpinButton *up;
QQuickSpinButton *down;
QValidator *validator;
QJSValue textFromValue;
QJSValue valueFromText;
mutable QJSValue textFromValue;
mutable QJSValue valueFromText;
};
int QQuickSpinBoxPrivate::boundValue(int value) const
@ -384,6 +384,11 @@ void QQuickSpinBox::setValidator(QValidator *validator)
QJSValue QQuickSpinBox::textFromValue() const
{
Q_D(const QQuickSpinBox);
if (!d->textFromValue.isCallable()) {
QQmlEngine *engine = qmlEngine(this);
if (engine)
d->textFromValue = engine->evaluate(QStringLiteral("function(value, locale) { return Number(value).toLocaleString(locale, 'f', 0); }"));
}
return d->textFromValue;
}
@ -420,6 +425,11 @@ void QQuickSpinBox::setTextFromValue(const QJSValue &callback)
QJSValue QQuickSpinBox::valueFromText() const
{
Q_D(const QQuickSpinBox);
if (!d->valueFromText.isCallable()) {
QQmlEngine *engine = qmlEngine(this);
if (engine)
d->valueFromText = engine->evaluate(QStringLiteral("function(text, locale) { return Number.fromLocaleString(locale, text); }"));
}
return d->valueFromText;
}
@ -587,19 +597,6 @@ void QQuickSpinBox::timerEvent(QTimerEvent *event)
}
}
void QQuickSpinBox::componentComplete()
{
Q_D(QQuickSpinBox);
QQuickControl::componentComplete();
QQmlEngine *engine = qmlEngine(this);
if (engine) {
if (!d->textFromValue.isCallable())
setTextFromValue(engine->evaluate(QStringLiteral("function(value, locale) { return Number(value).toLocaleString(locale, 'f', 0); }")));
if (!d->valueFromText.isCallable())
setValueFromText(engine->evaluate(QStringLiteral("function(text, locale) { return Number.fromLocaleString(locale, text); }")));
}
}
void QQuickSpinBox::itemChange(ItemChange change, const ItemChangeData &value)
{
Q_D(QQuickSpinBox);

View File

@ -121,7 +121,6 @@ protected:
void mouseUngrabEvent() Q_DECL_OVERRIDE;
void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
void componentComplete() Q_DECL_OVERRIDE;
void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE;
void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) Q_DECL_OVERRIDE;