object: Use std::vector to hold Objects GClosure's
We used a std::forward list to hold closure pointers in Object's to avoid adding a vector when not needed, but these structures are terribly slow as already pointed out in [1], and demonstrated even way poorer performances when testing signal connections (see [2], #485 (closed) and !758 (merged)), so get rid of them and just use vectors everywhere which can boost performances up to 95% in our tests.
This implies some more memory usage for each object, as we can't use a
std::vector
without the size member since C++11, but I think it's still
better, given that size of std::forward_list is still bigger when with
only two closures/vfuncs added (as each element requires two pointers).
Fixes: #485 (closed)
[1] https://github.com/3v1n0/stl-containers-benchmarks [2] 3v1n0/gjs$3608
It's quite crazy, but just switching to a std::vector
we easily go from:
Gjs-Console-Message: 02:51:56.398: connectToManyDifferentSignals(nConnections=15000, nHandlersEach=1): 1293.256 ms
Gjs-Console-Message: 02:51:56.450: emitAllSignals(nConnections=15000): 49.005 ms
Gjs-Console-Message: 02:51:56.540: emitAllSignalsRandomly(nConnections=15000): 73.072 ms
Gjs-Console-Message: 02:51:57.892: disconnectAllSignalsRandomly(nConnections=15000): 1342.209 ms
--------------------
Gjs-Console-Message: 02:51:58.061: connectToManyDifferentSignals(nConnections=5000, nHandlersEach=1): 145.047 ms
Gjs-Console-Message: 02:51:58.207: disconnectAllSignalsRepeatedly(nConnections=5000): 145.534 ms
--------------------
Gjs-Console-Message: 02:51:58.338: connectToManyDifferentSignals(nConnections=5000, nHandlersEach=1): 129.976 ms
Gjs-Console-Message: 02:51:58.525: disconnectAllSignalsRandomly(nConnections=5000): 183.376 ms
--------------------
Gjs-Console-Message: 02:52:15.683: connectToManyDifferentSignals(nConnections=500, nHandlersEach=100): 17155.549 ms
Gjs-Console-Message: 02:52:15.719: emitAllSignals(nConnections=500): 33.461 ms
Gjs-Console-Message: 02:52:15.751: emitAllSignalsRandomly(nConnections=500): 31.143 ms
Gjs-Console-Message: 02:52:44.384: disconnectAllSignalsRandomly(nConnections=50000): 28594.481 ms
to:
Gjs-Console-Message: 02:55:58.950: connectToManyDifferentSignals(nConnections=15000, nHandlers=1): 67.436 ms
Gjs-Console-Message: 02:55:58.996: emitAllSignals(nConnections=15000): 42.633 ms
Gjs-Console-Message: 02:55:59.073: emitAllSignalsRandomly(nConnections=15000): 62.663 ms
Gjs-Console-Message: 02:55:59.193: disconnectAllSignalsRandomly(nConnections=15000): 107.373 ms
--------------------
Gjs-Console-Message: 02:55:59.232: connectToManyDifferentSignals(nConnections=5000, nHandlers=1): 17.014 ms
Gjs-Console-Message: 02:55:59.253: disconnectAllSignalsRepeatedly(nConnections=5000): 20.323 ms
--------------------
Gjs-Console-Message: 02:55:59.268: connectToManyDifferentSignals(nConnections=5000, nHandlers=1): 14.406 ms
Gjs-Console-Message: 02:55:59.295: disconnectAllSignalsRandomly(nConnections=5000): 22.310 ms
--------------------
Gjs-Console-Message: 02:55:59.801: connectToManyDifferentSignals(nConnections=500, nHandlers=100): 503.625 ms
Gjs-Console-Message: 02:55:59.832: emitAllSignals(nConnections=500): 29.394 ms
Gjs-Console-Message: 02:55:59.863: emitAllSignalsRandomly(nConnections=500): 29.829 ms
Gjs-Console-Message: 02:56:00.622: disconnectAllSignalsRandomly(nConnections=50000): 720.122 ms
Which means:
std::forward_list | std::vector | |
---|---|---|
connectToManyDifferentSignals(15000, 1) | 1293,256 | 67,436 |
emitAllSignals(15000) | 49,005 | 42,633 |
emitAllSignalsRandomly(15000) | 73,072 | 62,663 |
disconnectAllSignalsRandomly(15000) | 1342,209 | 107,373 |
connectToManyDifferentSignals(5000, 1) | 145,047 | 17,014 |
disconnectAllSignalsRepeatedly(5000) | 145,534 | 20,323 |
connectToManyDifferentSignals(5000, 1) | 129,976 | 14,406 |
disconnectAllSignalsRandomly(5000) | 183,376 | 22,31 |
connectToManyDifferentSignals(500, 100) | 17155,549 | 503,625 |
emitAllSignals(500) | 33,461 | 29,394 |
emitAllSignalsRandomly(500) | 31,143 | 29,829 |
disconnectAllSignalsRandomly(500) | 28594,481 | 720,122 |