thautwarm / Site-32

thautwarm's blog page.
https://thautwarm.github.io/Site-32/
7 stars 1 forks source link

[note] unity python #13

Open thautwarm opened 2 years ago

thautwarm commented 2 years ago

为了用方便debug的语言做全平台开发(包括iOS和Android),实现了TraffyIR.UnityPython。

亮点是用了koka的思路,根据continuation是否存在来编译解释器的asm。做了benchmark,结果 (optimize=true的debug模式) 是非生成器代码比cpython略快(差距10%以内),非生成器比cpython慢一个数量级以内 (从1 yield 到 100_0000 比 cpython慢3倍)。

解释器的IR存在很大性能提升空间,目前每一次执行ir都会动态判断是否存在continuation。

如果不使用"inline threading"而使用字节码解释器,生成器代码会更快一点,但非生成器代码更慢,且不支持.NET native exception,且python try-catch-finally的字节码编译太烧脑,遂使用"inline threading"方案。

目前这点性能开销不是问题。一个有强力IDE支持、可热更新、动态执行、无伤兼容全平台的Python实现,意义重大。


目前TraffyIR.UnityPython 的限制:

  1. 不支持Python的一部分“罕见”元方法。例如,对比较操作只支持__eq____lt__(TODO: 支持le? 用户保证 leeqlt的相容?),且__lt____eq__必须返回bool

  2. 不支持type以外的其他的metaclass。但是支持__init_subclass__,足以应付大部分元编程场景。

  3. 不支持NotImplemented, 包括__ror__这些元方法

  4. 不支持用StopIteration做迭代终止。for循环的实现不依赖exception, raise StopIteration不会引起for loop正常退出,而是跑错误。

  5. 不支持raise a from cause。这主要是为了兼容.NET的native exception

  6. bool不是整数的子类型,True + 1报错。这一点python挺折磨人,而不实现bool <: int不仅减小工作量,也让我自己的使用体验更佳。

  7. int不是任意大整数而是int64floatfloat32。这是为了提升性能,顺便和unity交换数据时避免复杂cast。

  8. list.reverse不是O(1)的。list内部实现是.NET的List,因此reverse是O(n)操作 (TODO: 未来支持双向list实现?)

  9. 支持Python丰富的传参模式和参数验证,除了3.8引入的positional only arguments (XXX: TraffyIR.UnityPython基于Python 3.10,但不是所有feature都支持)

  10. yield/await/yield from不能出现在try-catch语句里,也不能出现在finally语句块里,但可以出现在try-finally语句块里。这是因为try语句实现使用了.NET的try-catch机制,与.NET有同样的限制。

  11. await Task.Yield()做运行时的特殊处理,行为上等同于yield但不开启async generator。

  12. async不耦合asyncio,实现正确的coroutine和thread分离机制。用户可以控制event loop,默认event loop被一个Unity根对象的coroutine执行。

thautwarm commented 2 years ago
  1. 支持并发,没有GIL。没有数据竞争的代码可以直接并发,不需要加锁。