Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.ruby > #4317 > unrolled thread

how to make eval() faster?

Started byZd Yu <zdyu2000@gmail.com>
First post2011-05-11 23:53 -0500
Last post2011-05-12 02:14 -0500
Articles 10 — 6 participants

Back to article view | Back to comp.lang.ruby


Contents

  how to make eval() faster? Zd Yu <zdyu2000@gmail.com> - 2011-05-11 23:53 -0500
    Re: how to make eval() faster? Joel VanderWerf <joelvanderwerf@gmail.com> - 2011-05-12 00:22 -0500
      Re: how to make eval() faster? Zd Yu <zdyu2000@gmail.com> - 2011-05-12 01:08 -0500
        Re: how to make eval() faster? Markus Schirp <mbj@seonic.net> - 2011-05-12 01:13 -0500
          Re: how to make eval() faster? Zd Yu <zdyu2000@gmail.com> - 2011-05-12 01:18 -0500
            Re: how to make eval() faster? Markus Schirp <mbj@seonic.net> - 2011-05-12 01:42 -0500
        Re: how to make eval() faster? Robert Klemme <shortcutter@googlemail.com> - 2011-05-12 02:26 -0500
    Re: how to make eval() faster? Zd Yu <zdyu2000@gmail.com> - 2011-05-12 01:37 -0500
      Re: how to make eval() faster? Stu <stu@rubyprogrammer.net> - 2011-05-12 01:55 -0500
        Re: how to make eval() faster? Xavier Noria <fxn@hashref.com> - 2011-05-12 02:14 -0500

#4317 — how to make eval() faster?

FromZd Yu <zdyu2000@gmail.com>
Date2011-05-11 23:53 -0500
Subjecthow to make eval() faster?
Message-ID<0229c425b2bf06473387c4f47263eb93@ruby-forum.com>
I use eval() to dynamically calculate performance metrics.

for example:
I have one configuration file that defines many performance metric
formulas, like IPC=instructions/cpu_cycles.

I also have another data file that contains many data samples, and I
just call the eval() for every data sample.

The problem is that I found eval() is really slow. is there a way to
make it faster?

-- 
Posted via http://www.ruby-forum.com/.

[toc] | [next] | [standalone]


#4320

FromJoel VanderWerf <joelvanderwerf@gmail.com>
Date2011-05-12 00:22 -0500
Message-ID<4DCB6EAA.7010101@gmail.com>
In reply to#4317
On 05/11/2011 09:53 PM, Zd Yu wrote:
> I use eval() to dynamically calculate performance metrics.
>
> for example:
> I have one configuration file that defines many performance metric
> formulas, like IPC=instructions/cpu_cycles.
>
> I also have another data file that contains many data samples, and I
> just call the eval() for every data sample.
>
> The problem is that I found eval() is really slow. is there a way to
> make it faster?

Can you eval your formulas into methods, and call the methods on the 
data samples?

[toc] | [prev] | [next] | [standalone]


#4321

FromZd Yu <zdyu2000@gmail.com>
Date2011-05-12 01:08 -0500
Message-ID<4c16a97bbcba0b1d4a451dc4f577e8be@ruby-forum.com>
In reply to#4320
Joel VanderWerf wrote in post #998154:
> On 05/11/2011 09:53 PM, Zd Yu wrote:
>> make it faster?
> Can you eval your formulas into methods, and call the methods on the
> data samples?

No. I need flexibility, i.e., allow users to define their own formulas 
in the configuration file.

-- 
Posted via http://www.ruby-forum.com/.

[toc] | [prev] | [next] | [standalone]


#4322

FromMarkus Schirp <mbj@seonic.net>
Date2011-05-12 01:13 -0500
Message-ID<4DCB7A92.9020505@seonic.net>
In reply to#4321
The configuration file can be plain ruby!
You can define your own DSL to manage the formulars.
So you can load the file once and the formulars do not have to be evaled...

On 05/12/2011 08:08 AM, Zd Yu wrote:
> Joel VanderWerf wrote in post #998154:
>> On 05/11/2011 09:53 PM, Zd Yu wrote:
>>> make it faster?
>> Can you eval your formulas into methods, and call the methods on the
>> data samples?
>
> No. I need flexibility, i.e., allow users to define their own formulas
> in the configuration file.
>

[toc] | [prev] | [next] | [standalone]


#4323

FromZd Yu <zdyu2000@gmail.com>
Date2011-05-12 01:18 -0500
Message-ID<21d0dceba517129670c3be73b83e50b3@ruby-forum.com>
In reply to#4322
Markus Schirp wrote in post #998159:
> The configuration file can be plain ruby!
> You can define your own DSL to manage the formulars.
> So you can load the file once and the formulars do not have to be
> evaled...

Nice catch. Actually I did try to implement it as DSL at the beginning, 
but finally I realized it is difficult to implement such a DSL in my 
problem. So at last I went to the XML format configuration way.

Below is the post I asked about DSL in 5 months ago:
http://www.ruby-forum.com/topic/696974#new

-- 
Posted via http://www.ruby-forum.com/.

[toc] | [prev] | [next] | [standalone]


#4325

FromMarkus Schirp <mbj@seonic.net>
Date2011-05-12 01:42 -0500
Message-ID<20110512064308.GA30754@mbj>
In reply to#4323
Too difficult?

The most "stupid simple" dsl is IMHO block based...

yourlib.rb
----------

module Yourlib
  class << self
    def define_processor(key,&block)
      processors << [key,&block]
    end

    def processors
      @processors ||= []
    end

    def run(row) # row should be an hash
      processors.each do |key,block|
        input[key]=block.call(row)
      end
    end
  end
end

settings.rb
-----------

require 'yourlib'

Yourlib.define_processor :outcome_a do |current|
  current[:event_a] * current[:event_b]
end

Yourlib.define_processor :outcome_b do |current|
  current[:outcome_b] = current[:event_b] * current[:outcome_a]
end

File.readlines(somepath) do |row|
  out = Yourlib.run(preprocess(row))
  do_something_fancy(out)
end

As long as your users do not use outcomes before they are produced you
can do calculations based on the outcomes...

If you need namespacing etc you can simply make an convention about the
output key names... and maybe about the input keys too... or try to add
(nested) namespacing.

I new this DSL is messy and redundant in usage, but a better approach
than using eval ;)

Regards,

Markus

On Thu, May 12, 2011 at 03:18:56PM +0900, Zd Yu wrote:
> Markus Schirp wrote in post #998159:
> > The configuration file can be plain ruby!
> > You can define your own DSL to manage the formulars.
> > So you can load the file once and the formulars do not have to be
> > evaled...
> 
> Nice catch. Actually I did try to implement it as DSL at the beginning, 
> but finally I realized it is difficult to implement such a DSL in my 
> problem. So at last I went to the XML format configuration way.
> 
> Below is the post I asked about DSL in 5 months ago:
> http://www.ruby-forum.com/topic/696974#new
> 
> -- 
> Posted via http://www.ruby-forum.com/.

[toc] | [prev] | [next] | [standalone]


#4328

FromRobert Klemme <shortcutter@googlemail.com>
Date2011-05-12 02:26 -0500
Message-ID<BANLkTiktso12PvHEENASgEVfoqV3TXZ68Q@mail.gmail.com>
In reply to#4321
On Thu, May 12, 2011 at 8:08 AM, Zd Yu <zdyu2000@gmail.com> wrote:
> Joel VanderWerf wrote in post #998154:
>> On 05/11/2011 09:53 PM, Zd Yu wrote:
>>> make it faster?
>> Can you eval your formulas into methods, and call the methods on the
>> data samples?
>
> No. I need flexibility, i.e., allow users to define their own formulas
> in the configuration file.

I believe you did not fully understand what Joel suggested.  You do
have that flexibility and you need to invoke eval only _once_ per
formula (for the initial compilation of the formula) but not for every
evaluation.  Example:

# really too simplistic!
formulas = Hash.new do |h, form|
  expr = form.sub(/\A.*?=\s*/, '')
  vars = expr.scan(/[a-z]\w*/i).uniq
  code = "lambda do |#{vars.join(', ')}| #{expr} end"
  p vars, code
  h[form] = eval(code)
end

# test
[
  'x = y * 2 + z',
  'z = y * x',
].each do |f|
  puts f

  10.times do |i|
    printf "%s: %d %d => %f\n", f, i, i*2, formulas[f][i, i*2]
  end
end

I'd prefer the DSL approach though.

Kind regards

robert

-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

[toc] | [prev] | [next] | [standalone]


#4324

FromZd Yu <zdyu2000@gmail.com>
Date2011-05-12 01:37 -0500
Message-ID<c6c0e8aa11c31286fc21cd4121d9f4a5@ruby-forum.com>
In reply to#4317
I just came up with an idea: I can parse the XML configuration file and 
generate a .rb file on the fly then invoke the rb file.

Although it brings much extra efforts, it can fix the performance issue.

-- 
Posted via http://www.ruby-forum.com/.

[toc] | [prev] | [next] | [standalone]


#4326

FromStu <stu@rubyprogrammer.net>
Date2011-05-12 01:55 -0500
Message-ID<BANLkTi=hVv+YOrPAME4R9P1Pj7R7VBiHJA@mail.gmail.com>
In reply to#4324
I was going to suggest a creating a tmp file with a generator. create
a sort of cached methods type thing.

This may fix your issue.

On Thu, May 12, 2011 at 1:37 AM, Zd Yu <zdyu2000@gmail.com> wrote:
> I just came up with an idea: I can parse the XML configuration file and
> generate a .rb file on the fly then invoke the rb file.
>
> Although it brings much extra efforts, it can fix the performance issue.
>
> --
> Posted via http://www.ruby-forum.com/.
>
>

[toc] | [prev] | [next] | [standalone]


#4327

FromXavier Noria <fxn@hashref.com>
Date2011-05-12 02:14 -0500
Message-ID<D9E028F4-084E-4D80-89F9-6F1B2F25D7BC@hashref.com>
In reply to#4326
No need to create a temp file. Unless the resulting code is huge, you can generate in memory and eval (once) the whole thing.

Top-posted from my iPad

El 12 May 2011, a les 08:55, Stu <stu@rubyprogrammer.net> va escriure:
> I was going to suggest a creating a tmp file with a generator. create
> a sort of cached methods type thing.
> 
> This may fix your issue.
> 
> On Thu, May 12, 2011 at 1:37 AM, Zd Yu <zdyu2000@gmail.com> wrote:
>> I just came up with an idea: I can parse the XML configuration file and
>> generate a .rb file on the fly then invoke the rb file.
>> 
>> Although it brings much extra efforts, it can fix the performance issue.
>> 
>> --
>> Posted via http://www.ruby-forum.com/.
>> 
>> 
> 

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.ruby


csiph-web