Closed jggatc closed 2 years ago
Suppose the issue is in the get function in transcrypt runtime. Tried some code refactoring experiments to optimize method calls, uncertain the impact on compatibility but obtained nearly a 5-fold increase in performance with the the following change in the get function:
original:
return function () {
var args = [] .slice.apply (arguments);
return func.apply (null, [aThis.__proxy__ ? aThis.__proxy__ : aThis] .concat (args));
};
revised:
return function () {
var args = [aThis.__proxy__ ? aThis.__proxy__ : aThis];
args.push.apply (args, arguments);
return func.apply (null, args);
};
transcrypt -n test_call.py console: function call: 0.003s method call: 0.052s
Refactoring of __get__
function in transcrypt runtime gained significant performance improvement.
Revision of __get__
function:
method handling with fcall pragma
value: function () {
var args = [aThis];
args.push.apply (args, arguments);
return func.apply (null, args);
},
method handling
return function () {
var args = [aThis.__proxy__ ? aThis.__proxy__ : aThis];
args.push.apply (args, arguments);
return func.apply (null, args);
};
Testing:
test_method_call.py
from time import time
class Cls:
def __init__(self):
self.count = 0
def update_count(self):
self.count += 1
cls = Cls()
def method_call():
for i in range(1000000):
cls.update_count()
t = time()
method_call()
tf = time() - t
print('method call: {}s'.format(round(tf,3)))
transcrypt -n test_method_call.py
Performance of revised vs original __get__
:
original __get__
(chrome)
method call: 0.252s
revised __get__
(chrome)
method call: 0.050s
original __get__
(firefox)
method call: 0.458s
revised __get__
(firefox)
method call: 0.117s
Performance of revised vs original __get__
using __pragma__ ('fcall')
:
original __get__
(chrome) fcall
method call: 0.219s
method call after 3*1M loops: 0.205s
revised __get__
(chrome) fcall
method call: 0.014s
method call after 3*1M loops: 0.006s
original __get__
(firefox) fcall
method call: 0.419s
method call after 3*1M loops: 0.413s
revised __get__
(firefox) fcall
method call: 0.078s
method call after 3*1M loops: 0.075s
Revised __get__
performance was increased 5x for chrome and 4x for firefox. Using fcall pragma, with original __get__
there is approx. 10-20% performance improvement, whereas with revised __get__
there is sum performance improvement of 18x for chrome and 6x for firefox. Chrome achieved 42x performance with revised __get__
after warmup of fcall bound function that is close to performance of function calls.
Similar revision can be applied to class method and static method handling. Have done limited testing of __get__
revision, not certain of compatibility impact.
Note: further testing show significant improvement for only simple methods.
Appears method calls are significantly slower than function calls, perhaps relates to JIT or JS function inlining. Tried running method_call repeatedly to warmup JS engine and to place cls.update in a var cls_update to avoid attr lookup overhead with only small improvement.
test_call.py:
Environment: Linux Python 3.9.6 Transcrypt 3.9.0 Chrome/Firefox