gpt4 book ai didi

python - 减少 Dart 中包装对象的数量

转载 作者:行者123 更新时间:2023-11-28 20:45:46 24 4
gpt4 key购买 nike

我的项目涉及将 Python 2.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代码为:

import 'lib/inbuilts.dart';
import 'dart:io';

fib(n) {
if (n <= new $PyNum(2)) {
return new $PyNum(1);
} else {
return (fib((n - new $PyNum(1))) + fib((n - new $PyNum(2))));
}
}

main() {
stdout.writeln(fib(new $PyNum(36)));
}

该代码运行良好,但在像这样存在极端递归的代码中,在每个函数实例中创建的过多包装对象会对代码的运行时间造成严重影响。例如解包的 Dart 代码:

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 语句。

  1. 0.134285 秒:没有包装器
  2. 0.645971 秒:使用简化的构造函数、运算符 <=(见下文)
    使用 const 构造函数没有显着差异(在转换为 JS 时可能更重要)
  3. 1.449707 秒:使用简化的构造函数
  4. 3.792590 秒:你的代码
class $PyNum2 {
final num _value;

const $PyNum2(this._value);

factory $PyNum2.from(value) {
switch ($getType2(value)) {
case 6:
return new $PyNum2(value);
break;
case 7:
try {
return new $PyNum2(num.parse(value));
} catch (ex) {
print("Invalid string literal for num parsing");
exit(1);
}
break;
case 5:
return new $PyNum2(value.value());
break;
default:
throw "Invalid input for num conversion";
}
}

value() => _value;
toString() => _value.toString();

operator +(other) => new $PyNum2(_value + other.value());
operator -(other) => new $PyNum2(_value - other.value());
operator *(other) => new $PyNum2(_value * other.value());
operator ~/(other) => new $PyNum2(_value ~/ other.value());
operator %(other) => new $PyNum2(_value % other.value());
operator ==(other) {
switch ($getType2(other)) {
case 6:
return _value == other;
case 5:
return _value == other.value();
default:
return false;
}
}
operator <(other) {
switch ($getType2(other)) {
case 6:
return _value < other;
case 5:
return _value < other.value();
default:
return true;
}
}
operator >(other) => !(this < other) && (this != other);
operator <=(other) => this.value() <= other.value(); //(this < other) || (this == other);
operator >=(other) => (this > other) || (this == other);
}

另见:

关于python - 减少 Dart 中包装对象的数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22504845/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com