ts wrote:
> I'm confused - what conversion is it trying to do? I thought
these two
> were equivalent:
> if(NIL_P(rbNum))
> if(Qnil == rbNum)
if you want to write the same with rb_scan_args(), you must write
if (rb_scan_args(argc, argv, "01", &rbNum)) {
rb_thread_wait_for(rb_time_interval(rbNum));
}
else {
rb_thread_sleep_forever();
}
and you see that the ruby version is faster
Guy Decoux
First things first. You're skirting the issue. It SHOULD work. There
is some sort of side effect happening, because the error is NOT coming
from process.c. I added some debug print statements directly into
process.c and rebuilt. I can't even get to that point before the error
is raised. This smells like a bug and/or some kind of global setting
being used some where.
Second, counting argc is not significantly faster than using
rb_scan_args(). Using the following code, counting argc was faster by
by .01 to .05 seconds over *ONE MILLION* iterations. That's 5.0e-008
per iteration. Rather insignificant don't you think?
/* foo.c
···
*
* The purpose of this class is to test the speed of manual counting
* of argc vs using rb_scan_args().
*/
#include "ruby.h"
#include <stdlib.h>
VALUE some_func(int num);
int other_func(VALUE rbNum);
VALUE some_func(int num){
VALUE rbNum = INT2FIX(num);
return rbNum;
}
int other_func(VALUE rbNum){
int y = FIX2INT(rbNum);
return y;
}
static VALUE test_scan(int argc, VALUE* argv){
VALUE rbNum;
rb_scan_args(argc,argv,"01",&rbNum);
if(NIL_P(rbNum)){
some_func(55);
}
else{
other_func(argv[0]);
}
return rbNum;
}
static VALUE test_count(int argc, VALUE* argv){
if(argc == 0){
some_func(55);
}
else if(argc == 1){
other_func(argv[0]);
}
else{
rb_raise(rb_eStandardError,"Wrong number of arguments");
}
return Qnil;
}
void Init_foo(){
VALUE cFoo = rb_define_class("Foo",rb_cObject);
rb_define_singleton_method(cFoo,"test_scan",test_scan,-1);
rb_define_singleton_method(cFoo,"test_count",test_count,-1);
}
# extconf.rb
require "mkmf"
create_makefile("foo")
# test_basic.rb
# Proof that you ought to be able to send 'nil'
# Adding debug print statements to the C code proves that it
# does what I intend.
$:.unshift Dir.pwd
require "foo"
Foo.test_scan(5) # works
Foo.test_scan # works
Foo.test_scan(nil) # works (!)
# test_speed.rb
$LOAD_PATH.unshift Dir.pwd
require "foo"
require "benchmark"
include Benchmark
bm do |x|
x.report("scan"){
1000000.times{ Foo.test_scan }
}
x.report("count"){
1000000.times{ Foo.test_count }
}
end
Results of benchmark using on Solaris 9, gcc 3.4.2, 500Mhz Sparc Ultra
IIe, 512 MB RAM:
user system total real
scan 3.220000 0.000000 3.220000 (3.224927)
count 3.170000 0.000000 3.170000 (3.179761)
Regards,
Dan