我的项目涉及到Python2.7代码到Dart代码的转换。为了完全模拟Python数据类型的所有特性,我在Dart中创建了包装器类,这些类扩展了原始Dart数据类型的功能,以匹配相应的Python类型。所有类型都有包装器,比如$PyNum代表数字,$PyString代表字符串等等。一切都很好,翻译的代码也很好。因为代码就像:
def fib(n):
if n <= 2:
return 1
else:
return fib (n - 1) + fib (n - 2)
print (fib(36))
相应生成的Dart代码为:
^{pr2}$代码运行良好,但在类似这样的代码中,存在极端递归,在每个函数实例上创建的过多包装对象会严重影响代码的运行时间。例如,未包装的省道代码:
import'dart:io';
fib(n) {
if (n <= 2) {
return 1;
} else {
return (fib((n - 1)) + fib((n - 2)));
}
}
main() {
stdout.writeln(fib(36));
}
由于明显的原因,它的运行速度几乎比包装好的代码快15倍。所有涉及包装数据类型的计算都会返回该类的新实例。对我来说,通过Dart模拟Python在其数据类型中提供的所有特性是绝对重要的,而包装是我目前唯一想到的事情。我尝试使用单例类来创建一个用于计算的公共对象,但在递归和线程化的情况下失败了。在
我的$PyNum包装类是这样的:
class $PyNum {
num _value;
$PyNum(value) {
switch ($getType(value)) {
case 6:
_value = value;
break;
case 7:
try {
_value = num.parse(value);
} catch (ex) {
print("Invalid string literal for num parsing");
exit(1);
}
break;
case 5:
_value = value.value();
break;
default:
throw "Invalid input for num conversion";
}
}
value() => _value;
toString() => _value.toString();
operator +(other) => new $PyNum(_value + other.value());
operator -(other) => new $PyNum(_value - other.value());
operator *(other) => new $PyNum(_value * other.value());
operator ~/(other) => new $PyNum(_value ~/ other.value());
operator |(other) => new $PyNum(_value | other.value());
operator &(other) => new $PyNum(_value & other.value());
operator ^(other) => new $PyNum(_value ^ other.value());
operator %(other) => new $PyNum(_value % other.value());
operator <<(other) => new $PyNum(_value << other.value());
operator >>(other) => new $PyNum(_value >> other.value());
operator ==(other) {
switch ($getType(other)) {
case 6:
return _value == other;
case 5:
return _value == other.value();
default:
return false;
}
}
operator <(other) {
switch ($getType(other)) {
case 6:
return _value < other;
case 5:
return _value < other.value();
default:
return true;
}
}
operator >(other) => !(this < other) && (this != other);
operator <=(other) => (this < other) || (this == other);
operator >=(other) => (this > other) || (this == other);
}
$getType(variable) {
if (variable is bool)
return 0;
else if (variable is $PyBool)
return 1;
else if (variable is $PyDict)
return 2;
else if (variable is $PyList)
return 3;
else if (variable is List)
return 4;
else if (variable is $PyNum)
return 5;
else if (variable is num)
return 6;
else if (variable is $PyString)
return 7;
else if (variable is $PyTuple)
return 8;
else
return -1;
}
const对象可以从这个类中提取出来吗?我不太清楚该怎么做。在
有没有其他方法可以有效地做到这一点,并且仍然能够模拟Python的所有特性?非常感谢任何帮助!在
我有一个类似的情况,我需要将附加信息与基本数据类型(如String、int、double,…)相连接
除了包装它们,我没有找到解决办法。在
您可以尝试通过以下方法优化这些包装类
编辑
-你肯定想去掉所有的switch语句。在
使用const构造函数并没有造成显著的区别(在转换为JS时可能更重要)
另请参见:
我没有尝试过这种方法,但是如果不包装对象,那么对于Python中需要的任何方法,可以使用类型case将其作为独立函数来实现。所以两者之间的任何共同点都会全速运转。只在一个python类中实现的方法会非常快,而且您只需要对python中的megamorphic进行大量类型测试。在
或者用Dart编写一个Python解释器。在
即使在您给出的示例中,如果使用const对象而不是每次都分配一个新的PyNum,也可能会做得更好。在
包装速度慢6.3倍的示例代码:
从该示例中删除了不必要的代码。在
相关问题 更多 >
编程相关推荐