Anybody can explain it clearer?
Ada yang bisa menjelaskan dg lebih gamblang?
[EMAIL PROTECTED]:~/Documents/spikes$ cat bm.rb
require 'benchmark'
include Benchmark
string1 = 'string %s'
string2 = 'string'
bm(6) do |x|
x.report('%') { 10_000_000.times { string1 % 'persen' } }
x.report('+') { 10_000_000.times { string2 + ' tambah' } }
end
[EMAIL PROTECTED]:~/Documents/spikes$ ruby bm.rb
user system total real
% 21.300000 1.920000 23.220000 ( 23.278688)
+ 12.750000 1.920000 14.670000 ( 14.683736)
Dugaan sementara ariekeren ya itu + cuma concat, sedang % bisa replace
jadi memang kelebihannya itu juga dibayar dengan performa, karena
sebetulnya sebelum tembak dengan sepuluh juta itu ariekeren pakai
sepuluh ribu hasil benchmarknya gini (semua sampai totalnya sama, beda
di realnya):
user system total real
% 0.020000 0.000000 0.020000 ( 0.024216)
+ 0.020000 0.000000 0.020000 ( 0.014881)
Silakan buat teman-teman yang mungkin ada analisis lebih lanjut?
Berikut ini source code di source code ruby (ya, pakai C)
File: /home/arie/Documents/sources/ruby/string.c
/*
* call-seq:
* str + other_str => new_str
*
* Concatenation---Returns a new <code>String</code> containing
* <i>other_str</i> concatenated to <i>str</i>.
*
* "Hello from " + self.to_s #=> "Hello from main"
*/
VALUE
rb_str_plus(VALUE str1, VALUE str2)
{
VALUE str3;
rb_encoding *enc;
StringValue(str2);
enc = rb_enc_check(str1, str2);
str3 = rb_str_new(0, RSTRING_LEN(str1)+RSTRING_LEN(str2));
memcpy(RSTRING_PTR(str3), RSTRING_PTR(str1), RSTRING_LEN(str1));
memcpy(RSTRING_PTR(str3) + RSTRING_LEN(str1),
RSTRING_PTR(str2), RSTRING_LEN(str2));
RSTRING_PTR(str3)[RSTRING_LEN(str3)] = '\0';
if (OBJ_TAINTED(str1) || OBJ_TAINTED(str2))
OBJ_TAINT(str3);
ENCODING_CODERANGE_SET(str3, rb_enc_to_index(enc),
ENC_CODERANGE_AND(ENC_CODERANGE(str1),
ENC_CODERANGE(str2)));
return str3;
}
/*
* call-seq:
* str % arg => new_str
*
* Format---Uses <i>str</i> as a format specification, and returns the
result
* of applying it to <i>arg</i>. If the format specification contains
more than
* one substitution, then <i>arg</i> must be an <code>Array</code>
containing
* the values to be substituted. See <code>Kernel::sprintf</code> for
details
* of the format string.
*
* "%05d" % 123 #=> "00123"
* "%-5s: %08x" % [ "ID", self.object_id ] #=> "ID : 200e14d6"
*/
static VALUE
rb_str_format_m(VALUE str, VALUE arg)
{
volatile VALUE tmp = rb_check_array_type(arg);
if (!NIL_P(tmp)) {
return rb_str_format(RARRAY_LEN(tmp), RARRAY_PTR(tmp), str);
}
return rb_str_format(1, &arg, str);
}
Berikut ini source code di source code rubinius (ya, pakai Ruby, dan
silakan spec'ing dan bm sendiri)
File: /home/arie/Documents/sources/rubinius/kernel/core/string.rb
# call-seq:
# str % arg => new_str
#
# Format---Uses <i>self</i> as a format specification, and returns the
result
# of applying it to <i>arg</i>. If the format specification contains
more than
# one substitution, then <i>arg</i> must be an <code>Array</code> containing
# the values to be substituted. See <code>Kernel::sprintf</code> for details
# of the format string.
#
# "%05d" % 123 #=> "00123"
# "%-5s: %08x" % [ "ID", self.id ] #=> "ID : 200e14d6"
def %(args)
Sprintf.new(self, *args).parse
end
# Concatenation --- Returns a new <code>String</code> containing
# <i>other</i> concatenated to <i>string</i>.
#
# "Hello from " + self.to_s #=> "Hello from main"
def +(other)
r = "#{self}#{StringValue(other)}"
r.taint if self.tainted? or other.tainted?
r
end
--
http://tinyurl.com/5w6lve
"Smalltalk, isn't it dead?" Hardly.
Randal Schwartz on Smalltalk