diff options
| author | Olivier De Cannière <olivier.decanniere@qt.io> | 2023-12-04 10:59:52 +0100 |
|---|---|---|
| committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2023-12-05 12:50:59 +0100 |
| commit | 4834aac7c9ae96e67254330dc054beb649785e63 (patch) | |
| tree | 6aa7ac29ae27091e45022d558918c36b8e39fcac /src/qml/jsruntime/qv4internalclass.cpp | |
| parent | 5e79d42c09a88a3614288503af99aa0c2792ad67 (diff) | |
JSEngine: Optimize QV4InternalClass for tests on MSVC
Running tst_ecmascripttests on MSVC in debug mode has become very slow
and times out the CI. Analysing the program reveals that most of the
slowdown is due to extensive wait times caused by locks. The test is run
on all threads by default and this constant synchronization tanks
performance.
A large amount of these locks come from the fact that, in debug mode,
MSVC standard containers use locks for most operations on iterators.
This patch changes the container of the internal class transitions from
an std::vector to a QVarLengthArray. This eliminates the iterator lock
problem. The QVarLengthArray is given one inline entry to store a value.
From the tests, it seems that the transitions contain only 0 or 1
entries about 84% of the time. In the remaining cases, more allocations
will be needed. The additional entry will also increase the size of the
containing object by 24 bytes. This should be a worthwhile tradeoff.
This change alone has a significant impact on the duration of the tests.
tst_ecmascripttests on 13900k with 32 threads
Debug MSVC Windows Debug GCC Linux
baseline: 2267s 104s
QVarLengthArray 569s (~ -73%) 102s (~ -2%)
This should be enough to no longer timeout the CI but many issues still
remain.
Change-Id: I69fefabc0375d76c817ef7d2d3b2e97dc1ace5bc
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4internalclass.cpp')
| -rw-r--r-- | src/qml/jsruntime/qv4internalclass.cpp | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index bf19b806e4..e4c401f5a7 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -227,7 +227,7 @@ void InternalClass::init(ExecutionEngine *engine) new (&propertyTable) PropertyHash(); new (&nameMap) SharedInternalClassData<PropertyKey>(engine); new (&propertyData) SharedInternalClassData<PropertyAttributes>(engine); - new (&transitions) std::vector<Transition>(); + new (&transitions) QVarLengthArray<Transition, 1>(); this->engine = engine; vtable = QV4::InternalClass::staticVTable(); @@ -244,7 +244,7 @@ void InternalClass::init(Heap::InternalClass *other) new (&propertyTable) PropertyHash(other->propertyTable); new (&nameMap) SharedInternalClassData<PropertyKey>(other->nameMap); new (&propertyData) SharedInternalClassData<PropertyAttributes>(other->propertyData); - new (&transitions) std::vector<Transition>(); + new (&transitions) QVarLengthArray<Transition, 1>(); engine = other->engine; vtable = other->vtable; @@ -275,7 +275,7 @@ void InternalClass::destroy() propertyTable.~PropertyHash(); nameMap.~SharedInternalClassData<PropertyKey>(); propertyData.~SharedInternalClassData<PropertyAttributes>(); - transitions.~vector<Transition>(); + transitions.~QVarLengthArray<Transition, 1>(); engine = nullptr; Base::destroy(); } @@ -302,7 +302,7 @@ void InternalClass::changeMember(QV4::Object *object, PropertyKey id, PropertyAt InternalClassTransition &InternalClass::lookupOrInsertTransition(const InternalClassTransition &t) { - std::vector<Transition>::iterator it = std::lower_bound(transitions.begin(), transitions.end(), t); + QVarLengthArray<Transition, 1>::iterator it = std::lower_bound(transitions.begin(), transitions.end(), t); if (it != transitions.end() && *it == t) { return *it; } else { @@ -334,7 +334,7 @@ static Heap::InternalClass *cleanInternalClass(Heap::InternalClass *orig) // We will generally add quite a few transitions here. We have 255 redundant ones. // We can expect at least as many significant ones in addition. - std::vector<InternalClassTransition> transitions; + QVarLengthArray<InternalClassTransition, 1> transitions; Scope scope(orig->engine); Scoped<QV4::InternalClass> child(scope, orig); |
