在这里,我们将给大家分享关于在Python中评估布尔表达式的知识,让您更了解python布尔值判断的本质,同时也会涉及到如何更有效地2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结
在这里,我们将给大家分享关于在Python中评估布尔表达式的知识,让您更了解python布尔值判断的本质,同时也会涉及到如何更有效地2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (t、2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR) 符号组成。、2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR...、IronPython中大规模评估表达式的表现的内容。
本文目录一览:- 在Python中评估布尔表达式(python布尔值判断)
- 2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (t
- 2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR) 符号组成。
- 2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR...
- IronPython中大规模评估表达式的表现
在Python中评估布尔表达式(python布尔值判断)
对象在Python中评估的真值是多少?
相关问题
- Python中对象的布尔值:有关覆盖对象评估方式的讨论
答案1
小编典典可以测试任何对象的真值,以在if或while条件中使用或用作以下布尔运算的操作数。以下值为“假”:
没有
假
任何数值类型的零,例如
0
,0L
,0.0
,0j
。任何空序列,例如
''''
,()
,[]
。任何空映射,例如
{}
。用户定义的类的实例,如果该类定义了
__nonzero__()
或__len__()
方法,则该方法返回整数0或bool
value时False
。所有其他值都被视为true,因此许多类型的对象始终为true。除非另有说明,否则具有布尔结果的操作和内置函数始终返回0或
False
false,返回1或True
true。(重要的例外:布尔运算符“或”和“和”始终返回其操作数之一。)
https://docs.python.org/2/library/stdtypes.html#truth-value-
testing
如前所述,您可以通过修改非零值来覆盖自定义对象。
2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (t
2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR) 符号组成。实现一个函数,算出有几种可使该表达式得出 result 值的括号方法。
福大大 答案 2021-06-03:
方法一:递归。
方法二:动态规划。
代码用 golang 编写。代码如下:
package main
import "fmt"
func main() {
express := "1&1&1"
desired := 1
ret0 := countEval0(express, desired)
ret1 := countEval1(express, desired)
ret2 := countEval2(express, desired)
fmt.Println(ret0, ret1, ret2)
}
func countEval0(express string, desired int) int {
if express == "" {
return 0
}
N := len(express)
dp := make([][]*Info, N)
for i := 0; i < N; i++ {
dp[i] = make([]*Info, N)
}
allInfo := ff(express, 0, len(express)-1, dp)
return twoSelectOne(desired == 1, allInfo.t, allInfo.f)
}
type Info struct {
t int
f int
}
func twoSelectOne(c bool, a int, b int) int {
if c {
return a
} else {
return b
}
}
// 限制:
// L...R上,一定有奇数个字符
// L位置的字符和R位置的字符,非0即1,不能是逻辑符号!
// 返回str[L...R]这一段,为true的方法数,和false的方法数
func ff(str string, L int, R int, dp [][]*Info) *Info {
if dp[L][R] != nil {
return dp[L][R]
}
t := 0
f := 0
if L == R {
t = twoSelectOne(str[L] == ''1'', 1, 0)
f = twoSelectOne(str[L] == ''0'', 1, 0)
} else { // L..R >=3
// 每一个种逻辑符号,split枚举的东西
// 都去试试最后结合
for split := L + 1; split < R; split += 2 {
leftInfo := ff(str, L, split-1, dp)
rightInfo := ff(str, split+1, R, dp)
a := leftInfo.t
b := leftInfo.f
c := rightInfo.t
d := rightInfo.f
switch str[split] {
case ''&'':
t += a * c
f += b*c + b*d + a*d
break
case ''|'':
t += a*c + a*d + b*c
f += b * d
break
case ''^'':
t += a*d + b*c
f += a*c + b*d
break
}
}
}
dp[L][R] = &Info{t, f}
return dp[L][R]
}
func countEval1(express string, desired int) int {
if express == "" {
return 0
}
return f(express, desired, 0, len(express)-1)
}
func f(str string, desired int, L int, R int) int {
if L == R {
if str[L] == ''1'' {
return desired
} else {
return desired ^ 1
}
}
res := 0
if desired == 1 {
for i := L + 1; i < R; i += 2 {
switch str[i] {
case ''&'':
res += f(str, 1, L, i-1) * f(str, 1, i+1, R)
break
case ''|'':
res += f(str, 1, L, i-1) * f(str, 0, i+1, R)
res += f(str, 0, L, i-1) * f(str, 1, i+1, R)
res += f(str, 1, L, i-1) * f(str, 1, i+1, R)
break
case ''^'':
res += f(str, 1, L, i-1) * f(str, 0, i+1, R)
res += f(str, 0, L, i-1) * f(str, 1, i+1, R)
break
}
}
} else {
for i := L + 1; i < R; i += 2 {
switch str[i] {
case ''&'':
res += f(str, 0, L, i-1) * f(str, 1, i+1, R)
res += f(str, 1, L, i-1) * f(str, 0, i+1, R)
res += f(str, 0, L, i-1) * f(str, 0, i+1, R)
break
case ''|'':
res += f(str, 0, L, i-1) * f(str, 0, i+1, R)
break
case ''^'':
res += f(str, 1, L, i-1) * f(str, 1, i+1, R)
res += f(str, 0, L, i-1) * f(str, 0, i+1, R)
break
}
}
}
return res
}
func countEval2(express string, desired int) int {
if express == "" {
return 0
}
N := len(express)
dp := make([][][]int, 2)
for i := 0; i < 2; i++ {
dp[i] = make([][]int, N)
for j := 0; j < N; j++ {
dp[i][j] = make([]int, N)
}
}
dp[0][0][0] = twoSelectOne(express[0] == ''0'', 1, 0)
dp[1][0][0] = dp[0][0][0] ^ 1
for i := 2; i < len(express); i += 2 {
dp[0][i][i] = twoSelectOne(express[i] == ''1'', 0, 1)
dp[1][i][i] = twoSelectOne(express[i] == ''0'', 0, 1)
for j := i - 2; j >= 0; j -= 2 {
for k := j; k < i; k += 2 {
if express[k+1] == ''&'' {
dp[1][j][i] += dp[1][j][k] * dp[1][k+2][i]
dp[0][j][i] += (dp[0][j][k]+dp[1][j][k])*dp[0][k+2][i] + dp[0][j][k]*dp[1][k+2][i]
} else if express[k+1] == ''|'' {
dp[1][j][i] += (dp[0][j][k]+dp[1][j][k])*dp[1][k+2][i] + dp[1][j][k]*dp[0][k+2][i]
dp[0][j][i] += dp[0][j][k] * dp[0][k+2][i]
} else {
dp[1][j][i] += dp[0][j][k]*dp[1][k+2][i] + dp[1][j][k]*dp[0][k+2][i]
dp[0][j][i] += dp[0][j][k]*dp[0][k+2][i] + dp[1][j][k]*dp[1][k+2][i]
}
}
}
}
return dp[desired][0][N-1]
}
执行结果如下:
***
[左神 java 代码](https://gitee.com/moonfdd/coding-for-great-offer/blob/main/src/class10/Code05_BooleanEvaluation.java)
本文分享自微信公众号 - 福大大架构师每日一题(gh_bbe96e5def84)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与 “OSC 源创计划”,欢迎正在阅读的你也加入,一起分享。
2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR) 符号组成。
2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR) 符号组成。实现一个函数,算出有几种可使该表达式得出 result 值的括号方法。
福大大 答案2021-06-03:
方法一:递归。
方法二:动态规划。
代码用golang编写。代码如下:
package main
import "fmt"
func main() {
express := "1&1&1"
desired := 1
ret0 := countEval0(express, desired)
ret1 := countEval1(express, desired)
ret2 := countEval2(express, desired)
fmt.Println(ret0, ret1, ret2)
}
func countEval0(express string, desired int) int {
if express == "" {
return 0
}
N := len(express)
dp := make([][]*Info, N)
for i := 0; i < N; i++ {
dp[i] = make([]*Info, N)
}
allInfo := ff(express, 0, len(express)-1, dp)
return twoSelectOne(desired == 1, allInfo.t, allInfo.f)
}
type Info struct {
t int
f int
}
func twoSelectOne(c bool, a int, b int) int {
if c {
return a
} else {
return b
}
}
// 限制:
// L...R上,一定有奇数个字符
// L位置的字符和R位置的字符,非0即1,不能是逻辑符号!
// 返回str[L...R]这一段,为true的方法数,和false的方法数
func ff(str string, L int, R int, dp [][]*Info) *Info {
if dp[L][R] != nil {
return dp[L][R]
}
t := 0
f := 0
if L == R {
t = twoSelectOne(str[L] == ''1'', 1, 0)
f = twoSelectOne(str[L] == ''0'', 1, 0)
} else { // L..R >=3
// 每一个种逻辑符号,split枚举的东西
// 都去试试最后结合
for split := L + 1; split < R; split += 2 {
leftInfo := ff(str, L, split-1, dp)
rightInfo := ff(str, split+1, R, dp)
a := leftInfo.t
b := leftInfo.f
c := rightInfo.t
d := rightInfo.f
switch str[split] {
case ''&'':
t += a * c
f += b*c + b*d + a*d
break
case ''|'':
t += a*c + a*d + b*c
f += b * d
break
case ''^'':
t += a*d + b*c
f += a*c + b*d
break
}
}
}
dp[L][R] = &Info{t, f}
return dp[L][R]
}
func countEval1(express string, desired int) int {
if express == "" {
return 0
}
return f(express, desired, 0, len(express)-1)
}
func f(str string, desired int, L int, R int) int {
if L == R {
if str[L] == ''1'' {
return desired
} else {
return desired ^ 1
}
}
res := 0
if desired == 1 {
for i := L + 1; i < R; i += 2 {
switch str[i] {
case ''&'':
res += f(str, 1, L, i-1) * f(str, 1, i+1, R)
break
case ''|'':
res += f(str, 1, L, i-1) * f(str, 0, i+1, R)
res += f(str, 0, L, i-1) * f(str, 1, i+1, R)
res += f(str, 1, L, i-1) * f(str, 1, i+1, R)
break
case ''^'':
res += f(str, 1, L, i-1) * f(str, 0, i+1, R)
res += f(str, 0, L, i-1) * f(str, 1, i+1, R)
break
}
}
} else {
for i := L + 1; i < R; i += 2 {
switch str[i] {
case ''&'':
res += f(str, 0, L, i-1) * f(str, 1, i+1, R)
res += f(str, 1, L, i-1) * f(str, 0, i+1, R)
res += f(str, 0, L, i-1) * f(str, 0, i+1, R)
break
case ''|'':
res += f(str, 0, L, i-1) * f(str, 0, i+1, R)
break
case ''^'':
res += f(str, 1, L, i-1) * f(str, 1, i+1, R)
res += f(str, 0, L, i-1) * f(str, 0, i+1, R)
break
}
}
}
return res
}
func countEval2(express string, desired int) int {
if express == "" {
return 0
}
N := len(express)
dp := make([][][]int, 2)
for i := 0; i < 2; i++ {
dp[i] = make([][]int, N)
for j := 0; j < N; j++ {
dp[i][j] = make([]int, N)
}
}
dp[0][0][0] = twoSelectOne(express[0] == ''0'', 1, 0)
dp[1][0][0] = dp[0][0][0] ^ 1
for i := 2; i < len(express); i += 2 {
dp[0][i][i] = twoSelectOne(express[i] == ''1'', 0, 1)
dp[1][i][i] = twoSelectOne(express[i] == ''0'', 0, 1)
for j := i - 2; j >= 0; j -= 2 {
for k := j; k < i; k += 2 {
if express[k+1] == ''&'' {
dp[1][j][i] += dp[1][j][k] * dp[1][k+2][i]
dp[0][j][i] += (dp[0][j][k]+dp[1][j][k])*dp[0][k+2][i] + dp[0][j][k]*dp[1][k+2][i]
} else if express[k+1] == ''|'' {
dp[1][j][i] += (dp[0][j][k]+dp[1][j][k])*dp[1][k+2][i] + dp[1][j][k]*dp[0][k+2][i]
dp[0][j][i] += dp[0][j][k] * dp[0][k+2][i]
} else {
dp[1][j][i] += dp[0][j][k]*dp[1][k+2][i] + dp[1][j][k]*dp[0][k+2][i]
dp[0][j][i] += dp[0][j][k]*dp[0][k+2][i] + dp[1][j][k]*dp[1][k+2][i]
}
}
}
}
return dp[desired][0][N-1]
}
执行结果如下:
左神java代码
总结
以上是小编为你收集整理的2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR) 符号组成。全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
原文地址:https://blog.csdn.net/weixin_48502062/article/details/117537426
2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR...
2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR) 符号组成。实现一个函数,算出有几种可使该表达式得出 result 值的括号方法。
福大大 答案2021-06-03:
方法一:递归。
方法二:动态规划。
代码用golang编写。代码如下:
package main
import "fmt"
func main() {
express := "1&1&1"
desired := 1
ret0 := countEval0(express, desired)
ret1 := countEval1(express, desired)
ret2 := countEval2(express, desired)
fmt.Println(ret0, ret1, ret2)
}
func countEval0(express string, desired int) int {
if express == "" {
return 0
}
N := len(express)
dp := make([][]*Info, N)
for i := 0; i < N; i++ {
dp[i] = make([]*Info, N)
}
allInfo := ff(express, 0, len(express)-1, dp)
return twoSelectOne(desired == 1, allInfo.t, allInfo.f)
}
type Info struct {
t int
f int
}
func twoSelectOne(c bool, a int, b int) int {
if c {
return a
} else {
return b
}
}
// 限制:
// L...R上,一定有奇数个字符
// L位置的字符和R位置的字符,非0即1,不能是逻辑符号!
// 返回str[L...R]这一段,为true的方法数,和false的方法数
func ff(str string, L int, R int, dp [][]*Info) *Info {
if dp[L][R] != nil {
return dp[L][R]
}
t := 0
f := 0
if L == R {
t = twoSelectOne(str[L] == ''1'', 1, 0)
f = twoSelectOne(str[L] == ''0'', 1, 0)
} else {
// L..R >=3
// 每一个种逻辑符号,split枚举的东西
// 都去试试最后结合
for split := L + 1; split < R; split += 2 {
leftInfo := ff(str, L, split-1, dp)
rightInfo := ff(str, split+1, R, dp)
a := leftInfo.t
b := leftInfo.f
c := rightInfo.t
d := rightInfo.f
switch str[split] {
case ''&'':
t += a * c
f += b*c + b*d + a*d
break
case ''|'':
t += a*c + a*d + b*c
f += b * d
break
case ''^'':
t += a*d + b*c
f += a*c + b*d
break
}
}
}
dp[L][R] = &Info{
t, f}
return dp[L][R]
}
func countEval1(express string, desired int) int {
if express == "" {
return 0
}
return f(express, desired, 0, len(express)-1)
}
func f(str string, desired int, L int, R int) int {
if L == R {
if str[L] == ''1'' {
return desired
} else {
return desired ^ 1
}
}
res := 0
if desired == 1 {
for i := L + 1; i < R; i += 2 {
switch str[i] {
case ''&'':
res += f(str, 1, L, i-1) * f(str, 1, i+1, R)
break
case ''|'':
res += f(str, 1, L, i-1) * f(str, 0, i+1, R)
res += f(str, 0, L, i-1) * f(str, 1, i+1, R)
res += f(str, 1, L, i-1) * f(str, 1, i+1, R)
break
case ''^'':
res += f(str, 1, L, i-1) * f(str, 0, i+1, R)
res += f(str, 0, L, i-1) * f(str, 1, i+1, R)
break
}
}
} else {
for i := L + 1; i < R; i += 2 {
switch str[i] {
case ''&'':
res += f(str, 0, L, i-1) * f(str, 1, i+1, R)
res += f(str, 1, L, i-1) * f(str, 0, i+1, R)
res += f(str, 0, L, i-1) * f(str, 0, i+1, R)
break
case ''|'':
res += f(str, 0, L, i-1) * f(str, 0, i+1, R)
break
case ''^'':
res += f(str, 1, L, i-1) * f(str, 1, i+1, R)
res += f(str, 0, L, i-1) * f(str, 0, i+1, R)
break
}
}
}
return res
}
func countEval2(express string, desired int) int {
if express == "" {
return 0
}
N := len(express)
dp := make([][][]int, 2)
for i := 0; i < 2; i++ {
dp[i] = make([][]int, N)
for j := 0; j < N; j++ {
dp[i][j] = make([]int, N)
}
}
dp[0][0][0] = twoSelectOne(express[0] == ''0'', 1, 0)
dp[1][0][0] = dp[0][0][0] ^ 1
for i := 2; i < len(express); i += 2 {
dp[0][i][i] = twoSelectOne(express[i] == ''1'', 0, 1)
dp[1][i][i] = twoSelectOne(express[i] == ''0'', 0, 1)
for j := i - 2; j >= 0; j -= 2 {
for k := j; k < i; k += 2 {
if express[k+1] == ''&'' {
dp[1][j][i] += dp[1][j][k] * dp[1][k+2][i]
dp[0][j][i] += (dp[0][j][k]+dp[1][j][k])*dp[0][k+2][i] + dp[0][j][k]*dp[1][k+2][i]
} else if express[k+1] == ''|'' {
dp[1][j][i] += (dp[0][j][k]+dp[1][j][k])*dp[1][k+2][i] + dp[1][j][k]*dp[0][k+2][i]
dp[0][j][i] += dp[0][j][k] * dp[0][k+2][i]
} else {
dp[1][j][i] += dp[0][j][k]*dp[1][k+2][i] + dp[1][j][k]*dp[0][k+2][i]
dp[0][j][i] += dp[0][j][k]*dp[0][k+2][i] + dp[1][j][k]*dp[1][k+2][i]
}
}
}
}
return dp[desired][0][N-1]
}
执行结果如下:
左神java代码
IronPython中大规模评估表达式的表现
我希望用户根据将在所有行上聚合的可用列提供一个或多个( python-)表达式.在静态上下文中它将是:
IDictionary<string,IList> table; // ... IList<int> a = table["a"] as IList<int>; IList<int> b = table["b"] as IList<int>; double sum = 0; for (int i = 0; i < n; i++) sum += (double)a[i] / b[i]; // Expression to sum up
对于n = 10 ^ 7,这在我的笔记本电脑上以0.270秒运行(win7 x64).对于具有两个int参数的委托替换表达式需要0.580秒,对于非类型委托,需要1.19秒.
用IronPython创建委托
IDictionary<string,IList> table; // ... var options = new Dictionary<string,object>(); options["Divisionoptions"] = PythonDivisionoptions.New; var engine = Python.CreateEngine(options); string expr = "a / b"; Func<int,int,double> f = engine.Execute("lambda a,b : " + expr); IList<int> a = table["a"] as IList<int>; IList<int> b = table["b"] as IList<int>; double sum = 0; for (int i = 0; i < n; i++) sum += f(a[i],b[i]);
它需要3.2秒(而使用Func< object,object,object>则需要5.1秒) – 因子4到5.5.这是我正在做的事情的预期开销吗?有什么可以改进的?
如果我有很多列,那么上面选择的方法就不够了.一种解决方案可以是确定每个表达式所需的列,并仅将它们用作参数.我尝试失败的另一个解决方案是使用ScriptScope并动态解析列.为此,我定义了一个RowIterator,它具有活动行的RowIndex和每列的属性.
class RowIterator { IList<int> la; IList<int> lb; public RowIterator(IList<int> a,IList<int> b) { this.la = a; this.lb = b; } public int RowIndex { get; set; } public int a { get { return la[RowIndex]; } } public int b { get { return lb[RowIndex]; } } }
ScriptScope可以从IDynamicMetaObjectProvider创建,我希望它可以通过C#的动态实现 – 但是在运行时engine.CreateScope(IDictionary)正在尝试调用,但失败了.
dynamic iterator = new RowIterator(a,b) as dynamic; var scope = engine.CreateScope(iterator); var expr = engine.CreateScriptSourceFromString("a / b").Compile(); double sum = 0; for (int i = 0; i < n; i++) { iterator.Index = i; sum += expr.Execute<double>(scope); }
接下来,我尝试让RowIterator从DynamicObject继承并使其成为一个正在运行的示例 – 具有可怕的性能:158秒.
class DynamicRowIterator : DynamicObject { Dictionary<string,object> members = new Dictionary<string,object>(); IList<int> la; IList<int> lb; public DynamicRowIterator(IList<int> a,IList<int> b) { this.la = a; this.lb = b; } public int RowIndex { get; set; } public int a { get { return la[RowIndex]; } } public int b { get { return lb[RowIndex]; } } public override bool TryGetMember(GetMemberBinder binder,out object result) { if (binder.Name == "a") // Why does this happen? { result = this.a; return true; } if (binder.Name == "b") { result = this.b; return true; } if (base.TryGetMember(binder,out result)) return true; if (members.TryGetValue(binder.Name,out result)) return true; return false; } public override bool TrySetMember(SetMemberBinder binder,object value) { if (base.TrySetMember(binder,value)) return true; members[binder.Name] = value; return true; } }
我对使用属性名称调用TryGetMember感到惊讶.从文档中我可以预期,TryGetMember只会被调用未定义的属性.
可能为了一个明智的性能,我需要为我的RowIterator实现IDynamicMetaObjectProvider以使用动态CallSites,但是找不到适合我的例子.在我的实验中,我不知道如何在BindGetMember中处理__builtins__:
class Iterator : IDynamicMetaObjectProvider { IList<int> la; IList<int> lb; public Iterator(IList<int> a,IList<int> b) { this.la = a; this.lb = b; } public int RowIndex { get; set; } public int a { get { return la[RowIndex]; } } public int b { get { return lb[RowIndex]; } } public DynamicMetaObject GetMetaObject(Expression parameter) { return new MetaObject(parameter,this); } private class MetaObject : DynamicMetaObject { internal MetaObject(Expression parameter,Iterator self) : base(parameter,BindingRestrictions.Empty,self) { } public override DynamicMetaObject BindGetMember(GetMemberBinder binder) { switch (binder.Name) { case "a": case "b": Type type = typeof(Iterator); string methodName = binder.Name; Expression[] parameters = new Expression[] { Expression.Constant(binder.Name) }; return new DynamicMetaObject( Expression.Call( Expression.Convert(Expression,LimitType),type.getmethod(methodName),parameters),BindingRestrictions.GetTypeRestriction(Expression,LimitType)); default: return base.BindGetMember(binder); } } } }
我确定我上面的代码不是最理想的,至少它还没有处理列的IDictionary.对于如何改进设计和/或性能的任何建议,我将不胜感激.
解决方法
第三个测试从一个天真(和坏的意图)表达树创建一个委托,没有任何花哨的东西,如呼叫端缓存,但它仍然比IronPython更快.
通过IronPython脚本编写表达式需要花费最多的时间.我的探查器向我展示了大部分时间花在Pythonops.Getvariable,PythonDictionary.TryGetValue和Pythonops.TryGetBoundAttr上.我认为还有改进的余地.
时序:
>直达:00:00:00.0052680
>通过词典:00:00:00.5577922
>编译代表:00:00:03.2733377
>脚本:00:00:09.0485515
这是代码:
public static void PythonBenchmark() { var engine = Python.CreateEngine(); int iterations = 1000; int count = 10000; int[] a = Enumerable.Range(0,count).ToArray(); int[] b = Enumerable.Range(0,count).ToArray(); Dictionary<string,object> symbols = new Dictionary<string,object> { { "a",a },{ "b",b } }; Func<int,object> calculate = engine.Execute("lambda i: a[i] + b[i]",engine.CreateScope(symbols)); var sw = Stopwatch.StartNew(); int sum = 0; for (int iteration = 0; iteration < iterations; iteration++) { for (int i = 0; i < count; i++) { sum += a[i] + b[i]; } } Console.WriteLine("Direct: " + sw.Elapsed); sw.Restart(); for (int iteration = 0; iteration < iterations; iteration++) { for (int i = 0; i < count; i++) { sum += ((int[])symbols["a"])[i] + ((int[])symbols["b"])[i]; } } Console.WriteLine("via Dictionary: " + sw.Elapsed); var indexExpression = Expression.Parameter(typeof(int),"index"); var indexerMethod = typeof(IList<int>).getmethod("get_Item"); var lookupMethod = typeof(IDictionary<string,object>).getmethod("get_Item"); Func<string,Expression> getSymbolExpression = symbol => Expression.Call(Expression.Constant(symbols),lookupMethod,Expression.Constant(symbol)); var addExpression = Expression.Add( Expression.Call(Expression.Convert(getSymbolExpression("a"),typeof(IList<int>)),indexerMethod,indexExpression),Expression.Call(Expression.Convert(getSymbolExpression("b"),indexExpression)); var compiledFunc = Expression.Lambda<Func<int,object>>(Expression.Convert(addExpression,typeof(object)),indexExpression).Compile(); sw.Restart(); for (int iteration = 0; iteration < iterations; iteration++) { for (int i = 0; i < count; i++) { sum += (int)compiledFunc(i); } } Console.WriteLine("Compiled Delegate: " + sw.Elapsed); sw.Restart(); for (int iteration = 0; iteration < iterations; iteration++) { for (int i = 0; i < count; i++) { sum += (int)calculate(i); } } Console.WriteLine("Scripted: " + sw.Elapsed); Console.WriteLine(sum); // make sure cannot be optimized away }
今天关于在Python中评估布尔表达式和python布尔值判断的介绍到此结束,谢谢您的阅读,有关2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (t、2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR) 符号组成。、2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR...、IronPython中大规模评估表达式的表现等更多相关知识的信息可以在本站进行查询。
本文标签: