[#1816] Ruby 1.5.3 under Tru64 (Alpha)? — Clemens Hintze <clemens.hintze@...>

Hi all,

17 messages 2000/03/14

[#1989] English Ruby/Gtk Tutorial? — schneik@...

18 messages 2000/03/17

[#2241] setter() for local variables — ts <decoux@...>

18 messages 2000/03/29

[ruby-talk:02206] Re: Scripting and OO -- thought question

From: Clemens Hintze <c.hintze@...>
Date: 2000-03-28 02:34:18 UTC
List: ruby-talk #2206
David Douthitt writes:

...

> Well, the Ruby version used to do:
> 
>    LogFile.open.readlines.each { }
> 
> Now it does
> 
>    LogFile.open { |f| f.readlines.each { } }
> 

...

> This following ruby code was replaced entirely by (ksh):
> 
>    for sys in $*
>    do
>       egrep ":.. [^ ]* (in\.|)$sys" $MESSAGES > ${sys}
>    done
> 
> (MESSAGES=/var/log/messages)
> 
> And it FLIES!  Here is the ruby code:
         ^^^^^
Arrrggghhhhh!!!

> 
> #!/usr/bin/ruby

...

> systems = Array.new
> 
> class String
>    def systemName
>       self.scan("^... .. ..:..:.. ([^ ]*)")
>    end
> end
> 
> File.open("/var/log/messages").each { |line|
>    line.chomp!
> #  sys = line.scan("^... .. ..:..:.. ([^ ]*)")
>    sys = line.systemName
> 
>    systems = systems | sys
> 
>    if not ARGV.include?(sys[0][0])
>       print("    ", line, "\n")
>    end
>    }

Of course you have guessed it! Somebody has to complain now. This
comparsion is totally unfair. And I assume you know this fact!!! :-(

In your example 'grep' will do nearly all of the true work. The ksh
will serve only as wrapper and call 'grep' once for every system you
have passed via command line.

The ruby program, however, will do real work. No external program
is helping. Of course, most often a C program will be faster than a
plain Ruby one. But this will not save you ;-)))

Do you remember? In the original thread I had said: "I strongly
believe that my app using scripting and C together would be nearly as
performant as his one coded in C/C++ only." :-)))))))))

Okay, here we go:


Following is your example. I had to change the regexp a little bit,
otherwise it wouldn't match my syslog entries:



Okay. Now the files necessary for Ruby. First the extconf.rb file that
configure our extension;



Then our Ruby program that do nearly the same as your ksh script
(means nothing ;-):



Then the extension module, the C code. This file serves only as prove
of concept and is not bullet proof coded (in fact no any error
handling):



So now I have done the following:

------------------------------------------------
Script started on Tue Mar 28 04:12:24 2000
cle@qiao > ruby extconf.rb 
creating Makefile
cle@qiao > make
gcc -fPIC -I/usr/local/lib/ruby/1.5/i586-linux -g -O2 -fPIC  -I/usr/local/include    -c _sysgrep.c -o _sysgrep.o
gcc -shared   -o _sysgrep.so _sysgrep.o -lc 
cle@qiao > time sysgrep.ksh qiao qiao qiao qiao   # your example

real	0m4.859s
user	0m1.990s
sys	0m1.250s
cle@qiao > time sysgrep.rb qiao qiao qiao qiao    # my one

real    0m4.169s
user    0m2.070s
sys     0m1.080s                   
cle@qiao > exit

Script done on Tue Mar 28 04:13:13 2000
------------------------------------------------

As you can see, now Ruby is even faster than your ksh solution. Of
course this evidence is not fair too, but in confirmation with my
cited statement above! :-)

And it is not more unfair than yours ;-))))

[nice code deleted ...]

If you would try to do this all in ksh *without* help from grep and in
the same complexity as your fine Ruby script, I guess you will go mad!
And I have my doubts, if this *pure* ksh solution would be faster than
the Ruby's one ;-)

> Now aren't you glad you asked for code?  :-)

I am for sure. I love to see code written by others. I can learn from
anyone! :-)

\cle

-- 
Clemens Hintze  mailto: c.hintze@gmx.net

Attachments (4)

sysgrep.ksh (115 Bytes, application/x-sh)
extconf.rb (42 Bytes, text/x-ruby)
require "mkmf"
create_makefile "_sysgrep"
sysgrep.rb (122 Bytes, application/x-sh)
_sysgrep.c (616 Bytes, text/x-c++src)
#include <ruby.h>
#include <strings.h>


#define MAXLIN 3072


static VALUE grep(VALUE self, VALUE offset, VALUE host, VALUE infile)
{
   FILE* fpin = fopen(RSTRING(infile)->ptr, "r");
   FILE* fpout = fopen(RSTRING(host)->ptr,"w");
   char  line[MAXLIN];
   char* sys = RSTRING(host)->ptr;
   long  syslen = RSTRING(host)->len;
   char* syspos = line + NUM2LONG(offset);

   while (fgets(line, MAXLIN, fpin))
      if (strncmp(syspos, sys, syslen) == 0)
         fprintf(fpout, line);

   fclose(fpin);
   fclose(fpout);

   return Qnil;
}


void Init__sysgrep()
{
   rb_define_global_function("grep", grep, 3);
}

In This Thread