mruby-io: implement print in c for improved performance

Moved IO#print from Ruby to C implementation to reduce boundary
crossing overhead. Maintains full compatibility with automatic
to_s conversion for all arguments.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-08-16 12:43:35 +09:00
parent dd9053d0cf
commit 85ca24622a
2 changed files with 31 additions and 20 deletions
-20
View File
@@ -305,26 +305,6 @@ class IO
end
#
# call-seq:
# ios.print() -> nil
# ios.print(obj, ...) -> nil
#
# Writes the given object(s) to ios. Objects that aren't strings will be
# converted by calling their to_s method. With no argument, prints the
# contents of the variable $_.
#
# $stdout.print("This is ", 100, " percent.\n")
# This is 100 percent.
#
def print(*args)
i = 0
len = args.size
while i < len
write args[i].to_s
i += 1
end
end
#
# call-seq:
+31
View File
@@ -1218,6 +1218,36 @@ io_puts(mrb_state *mrb, mrb_value io)
return mrb_nil_value();
}
/*
* call-seq:
* ios.print() -> nil
* ios.print(obj, ...) -> nil
*
* Writes the given object(s) to ios. Objects that aren't strings will be
* converted by calling their to_s method.
*/
static mrb_value
io_print(mrb_state *mrb, mrb_value io)
{
struct mrb_io *fptr = io_get_write_fptr(mrb, io);
int fd = io_get_write_fd(fptr);
/* Prepare IO for writing (handle read buffer adjustment) */
io_prepare_write(mrb, fptr);
mrb_value *argv;
mrb_int argc;
mrb_get_args(mrb, "*", &argv, &argc);
/* Convert each argument to string and write it */
for (mrb_int i = 0; i < argc; i++) {
mrb_value str = mrb_obj_as_string(mrb, argv[i]);
fd_write(mrb, fd, str);
}
return mrb_nil_value();
}
static mrb_value
io_close(mrb_state *mrb, mrb_value io)
{
@@ -2226,6 +2256,7 @@ mrb_init_io(mrb_state *mrb)
mrb_define_method_id(mrb, io, MRB_SYM(fileno), io_fileno, MRB_ARGS_NONE());
mrb_define_method_id(mrb, io, MRB_SYM(write), io_write, MRB_ARGS_ANY()); /* 15.2.20.5.20 */
mrb_define_method_id(mrb, io, MRB_SYM(puts), io_puts, MRB_ARGS_ANY());
mrb_define_method_id(mrb, io, MRB_SYM(print), io_print, MRB_ARGS_ANY());
mrb_define_method_id(mrb, io, MRB_SYM(pread), io_pread, MRB_ARGS_ANY()); /* Ruby 2.5 feature */
mrb_define_method_id(mrb, io, MRB_SYM(pwrite), io_pwrite, MRB_ARGS_ANY()); /* Ruby 2.5 feature */
mrb_define_method_id(mrb, io, MRB_SYM(getbyte), io_getbyte, MRB_ARGS_NONE());