зеркало из https://github.com/github/ruby.git
time.c (time_strftime): avoid garbage in common case
strftime format strings which are dynamically-generated will benefit from avoiding garbage, here. * time.c (time_strftime): use rb_str_tmp_frozen_{acquire,release} * test/ruby/test_time.rb (test_strftime_no_hidden_garbage): new test git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57476 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
ed28d151a3
Коммит
9b69e9fafc
|
@ -1090,6 +1090,17 @@ class TestTime < Test::Unit::TestCase
|
||||||
assert_equal("366", t.strftime("%j"))
|
assert_equal("366", t.strftime("%j"))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_strftime_no_hidden_garbage
|
||||||
|
fmt = %w(Y m d).map { |x| "%#{x}" }.join('-') # defeats optimization
|
||||||
|
t = Time.at(0)
|
||||||
|
ObjectSpace.count_objects(res = {}) # creates strings on first call
|
||||||
|
before = ObjectSpace.count_objects(res)[:T_STRING]
|
||||||
|
val = t.strftime(fmt)
|
||||||
|
after = ObjectSpace.count_objects(res)[:T_STRING]
|
||||||
|
assert_equal before + 1, after, 'only new string is the created one'
|
||||||
|
assert_equal '1970-01-01', val
|
||||||
|
end
|
||||||
|
|
||||||
def test_num_exact_error
|
def test_num_exact_error
|
||||||
bad = EnvUtil.labeled_class("BadValue").new
|
bad = EnvUtil.labeled_class("BadValue").new
|
||||||
x = EnvUtil.labeled_class("Inexact") do
|
x = EnvUtil.labeled_class("Inexact") do
|
||||||
|
|
8
time.c
8
time.c
|
@ -4422,6 +4422,7 @@ time_strftime(VALUE time, VALUE format)
|
||||||
const char *fmt;
|
const char *fmt;
|
||||||
long len;
|
long len;
|
||||||
rb_encoding *enc;
|
rb_encoding *enc;
|
||||||
|
VALUE tmp;
|
||||||
|
|
||||||
GetTimeval(time, tobj);
|
GetTimeval(time, tobj);
|
||||||
MAKE_TM(time, tobj);
|
MAKE_TM(time, tobj);
|
||||||
|
@ -4429,9 +4430,9 @@ time_strftime(VALUE time, VALUE format)
|
||||||
if (!rb_enc_str_asciicompat_p(format)) {
|
if (!rb_enc_str_asciicompat_p(format)) {
|
||||||
rb_raise(rb_eArgError, "format should have ASCII compatible encoding");
|
rb_raise(rb_eArgError, "format should have ASCII compatible encoding");
|
||||||
}
|
}
|
||||||
format = rb_str_new4(format);
|
tmp = rb_str_tmp_frozen_acquire(format);
|
||||||
fmt = RSTRING_PTR(format);
|
fmt = RSTRING_PTR(tmp);
|
||||||
len = RSTRING_LEN(format);
|
len = RSTRING_LEN(tmp);
|
||||||
enc = rb_enc_get(format);
|
enc = rb_enc_get(format);
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
rb_warning("strftime called with empty format string");
|
rb_warning("strftime called with empty format string");
|
||||||
|
@ -4440,6 +4441,7 @@ time_strftime(VALUE time, VALUE format)
|
||||||
else {
|
else {
|
||||||
VALUE str = rb_strftime_alloc(fmt, len, enc, &tobj->vtm, tobj->timew,
|
VALUE str = rb_strftime_alloc(fmt, len, enc, &tobj->vtm, tobj->timew,
|
||||||
TIME_UTC_P(tobj));
|
TIME_UTC_P(tobj));
|
||||||
|
rb_str_tmp_frozen_release(format, tmp);
|
||||||
if (!str) rb_raise(rb_eArgError, "invalid format: %"PRIsVALUE, format);
|
if (!str) rb_raise(rb_eArgError, "invalid format: %"PRIsVALUE, format);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче