ruby按位积

ruby按位积,ruby,performance,Ruby,Performance,我有一个赋值,我必须写一个函数,它接受两个整数并返回它的位积。位积等于这两者之间所有数字的位和(&) 例如:251和253的位积为: irb(main):164:0> 251 & 252 => 248 irb(main):165:0> 252 & 253 => 252 irb(main):166:0> 248 & 252 => 248 # this a bitwise & of these two between 251 &am

我有一个赋值,我必须写一个函数,它接受两个整数并返回它的位积。位积等于这两者之间所有数字的位和(
&

例如:
251
253
的位积为:

irb(main):164:0> 251 & 252
=> 248
irb(main):165:0> 252 & 253
=> 252
irb(main):166:0> 248 & 252
=> 248 # this a bitwise & of these two between 251 & 253
我的职能:

def solution(m,n)
  (m..n).to_a.inject{|sum, x| sum &= x}
end
测试:

该计划的评估:

正确率100%
性能0%

谁能解释一下这个功能的性能是什么?提前谢谢

编辑 由于此处未定义性能,您能否提供功能分析,例如,真正的大输入和批评/建议更好/更有效的解决方案


p、 对于评论的家伙,我会按照建议

根据我的评论,您可以使用基准测试进行试验:

def solution(m,n)
  (m..n).to_a.inject{|sum, x| sum &= x}
end

def solution2(m,n)
  (m..n).reduce(:&)
end

n = 50000
Benchmark.bm(7) do |b|
  b.report("orig:") { n.times do; solution(128,253); end }
  b.report("new: ") { n.times do; solution2(128,253); end }
end
以下是我得到的:

              user     system      total        real
orig:     1.560000   0.000000   1.560000 (  1.557156)
new:      0.640000   0.000000   0.640000 (  0.634063)

您似乎别无选择,只能执行上述操作,试验以找到更快的算法,并运行测试,直到您在性能表上注册。

在我的评论之后,您可以使用基准测试进行试验:

def solution(m,n)
  (m..n).to_a.inject{|sum, x| sum &= x}
end

def solution2(m,n)
  (m..n).reduce(:&)
end

n = 50000
Benchmark.bm(7) do |b|
  b.report("orig:") { n.times do; solution(128,253); end }
  b.report("new: ") { n.times do; solution2(128,253); end }
end
以下是我得到的:

              user     system      total        real
orig:     1.560000   0.000000   1.560000 (  1.557156)
new:      0.640000   0.000000   0.640000 (  0.634063)

您似乎别无选择,只能执行上述操作,试验以找到更快的算法,并运行测试,直到您在性能表上注册。

在我的评论之后,您可以使用基准测试进行试验:

def solution(m,n)
  (m..n).to_a.inject{|sum, x| sum &= x}
end

def solution2(m,n)
  (m..n).reduce(:&)
end

n = 50000
Benchmark.bm(7) do |b|
  b.report("orig:") { n.times do; solution(128,253); end }
  b.report("new: ") { n.times do; solution2(128,253); end }
end
以下是我得到的:

              user     system      total        real
orig:     1.560000   0.000000   1.560000 (  1.557156)
new:      0.640000   0.000000   0.640000 (  0.634063)

您似乎别无选择,只能执行上述操作,试验以找到更快的算法,并运行测试,直到您在性能表上注册。

在我的评论之后,您可以使用基准测试进行试验:

def solution(m,n)
  (m..n).to_a.inject{|sum, x| sum &= x}
end

def solution2(m,n)
  (m..n).reduce(:&)
end

n = 50000
Benchmark.bm(7) do |b|
  b.report("orig:") { n.times do; solution(128,253); end }
  b.report("new: ") { n.times do; solution2(128,253); end }
end
以下是我得到的:

              user     system      total        real
orig:     1.560000   0.000000   1.560000 (  1.557156)
new:      0.640000   0.000000   0.640000 (  0.634063)

您似乎别无选择,只能执行上述操作,尝试找到更快的算法,然后运行测试,直到您在性能表上注册。

这里最明显的性能问题是转换为数组(
到a
),这不是必须的。您可以调用
reduce
inject
(看起来相同)任何
可枚举的
范围也包括它
Enumerable
基本上就是能够产生有限(这是有争议的,但基本上是正确的)元素序列的所有东西<如果将代码>范围
视为一组整数,则它似乎是合适的

为了迭代包含此范围内元素的数组,首先创建一个数组并用元素填充它(通过迭代
范围
)。然后应用您的操作在结果数组上迭代。因此,您创建了一个数组,用于对其进行迭代、填充、使用和丢弃。如果范围很大的话,需要相当多的内存分配才能做到这一点

下一个问题并不重要,但减少了代码量,需要了解Ruby中操作符的内部实现。当你写
a&b
时,你实际上是在做
a.&(b)
:对一个号码调用
&
方法

在块中得到的
sum
实际上不是某种
累加器
,实际上不需要在那里赋值,
sum
是一个中间值,添加新元素的结果实际上应该是一个返回值。因为赋值返回赋值,所以它甚至可以这样工作。这方面的证据如下:

(251..253).inject{|sum, x| sum & x } # => 248, as expected
…事实证明,这个块很简单:取一个值,用另一个值调用它的方法。因为
inject
在每次迭代中都会获取一对值,所以您可以给它一个方法名,让它处理这种情况。Ruby中的方法名称通常使用如下符号引用:

(251..253).inject(:&) # => 248, as expected
好吧,代码少了一倍,动作少了一倍,对象少了一倍,但结果是一样的

def solution(m,n)
  (m..n).inject(:&)
end
我们还没有仔细研究
inject
。你能在性能方面击败
inject
吗?不太可能,这是一个C方法,在这里使用它完全是为了它的目的,您可以使用gems
pry
pry doc
(安装、启动
pry
并键入
显示源代码范围#inject
):


这里最明显的性能问题是到数组的转换(
到a
),这不是必需的。您可以调用
reduce
inject
(看起来相同)任何
可枚举的
范围也包括它
Enumerable
基本上就是能够产生有限(这是有争议的,但基本上是正确的)元素序列的所有东西<如果将代码>范围
视为一组整数,则它似乎是合适的

为了迭代包含此范围内元素的数组,首先创建一个数组并用元素填充它(通过迭代
范围
)。然后应用您的操作在结果数组上迭代。因此,您创建了一个数组,用于对其进行迭代、填充、使用和丢弃。如果范围很大的话,需要相当多的内存分配才能做到这一点

下一个问题并不重要,但减少了代码量,需要了解Ruby中操作符的内部实现。当你写
a&b
时,你实际上是在做
a.&(b)
:对一个号码调用
&
方法

在块中得到的
sum
实际上不是某种
累加器
,实际上不需要在那里赋值,
sum
是一个中间值,添加新元素的结果实际上应该是一个返回值。因为赋值返回赋值,所以它甚至可以这样工作。这方面的证据如下:

(251..253).inject{|sum, x| sum & x } # => 248, as expected
…事实证明,这个块很简单:取一个值,用另一个值调用它的方法。因为
inject
在每次迭代中都会获取一对值,所以您可以给它一个方法名,让它处理这种情况。Ruby中的方法名称通常使用如下符号引用:

(251..253).inject(:&) # => 248, as expected
好吧,代码少了一倍,动作少了一倍,对象也少了一倍,不过r还是一样