TranscryptOrg / Transcrypt

Python 3.9 to JavaScript compiler - Lean, fast, open!
https://www.transcrypt.org
Apache License 2.0
2.85k stars 214 forks source link

problem with fcall __pragma__ #819

Open jggatc opened 2 years ago

jggatc commented 2 years ago

Discovered an issue with __pragma__ ('fcall') when a method is an alias identifier such as update. Using fcall pragma, update_count method performance increased 16% (to 24% after 4M calls), whereas update method performance decreased 2-fold.

class Cls:
    def __init__(self):
        self.count = count
    def update_count(self):
        self.count += 1
cls = Cls()

without __pragma__ ('fcall'): loop of 1M calls: 1M cls.update_count calls: 0.268s loop * 4: 1M cls.update_count calls: 0.240s

with __pragma__ ('fcall'): loop of 1M calls: 1M cls.update_count calls: 0.226s loop * 4: 1M cls.update_count calls: 0.203s

class Cls:
    def __init__(self):
        self.count = count
    def update(self):
        self.count += 1
cls = Cls()

without __pragma__ ('fcall'): loop of 1M calls: 1M cls.update calls: 0.258s loop * 4: 1M cls.update calls: 0.242s

with __pragma__ ('fcall'): loop of 1M calls: 1M cls.update calls: 0.516s loop * 4: 1M cls.update calls: 0.528s

The issue is due to incorrectly handling update, which should be aliased py_update. The JS code for the methods with fcall pragma:

update_count method (last arg is 'update_count'):

get update_count () {return __get__ (this, function (self) {
self.count++;
}, 'update_count');}

update method (last arg is 'update', should be 'py_update'):

get py_update () {return __get__ (this, function (self) {
self.count++;
}, 'update');}

Environment: Linux Python 3.9.6 Transcrypt 3.9.0 Chrome