String#=の挙動 on Ruby1.9.1p0(MacOS 10.5.7)

String#<<で連結した文字列を別の変数に代入しようとした場合、
リファレンス(ポインタ)の代入ではなく、値のコピーが行われている
(文字列をディープコピーして生成したオブジェクトのリファレンス
(ポインタ)が代入されている?)のではないかと思う。常に行うのではなく、
特定のケースで行うのかもしれない。


「String#<<で連結した文字列をString#=で別の変数に代入する処理を
一万回行った」場合の処理時間が、「String#<<での文字列連結を一万回
繰り返し、連結した文字列のString#=での別の変数への代入を一回行った」
場合の10倍以上になる。リファレンス(ポインタ)の代入が行われているの
ならこのような結果にはならないはず。


一万回行った場合は下記を一万回繰り返す。

String#<<で連結
連結した文字列をString#=で別の変数(変数A)に代入

一回行った場合は下記を一万回繰り返し

String#<<で連結

最後に

連結した文字列をString#=で別の変数(変数A)に代入

(同一オブジェクトに対してString#<<している。)


既に修正されている可能性あり。


Rubyの詳細なバージョンはruby 1.9.1p0 (2009-01-30 revision 21907)
[i386-darwin9]。


[追記]
Object#object_idで返される数値は同じ、つまりRubyスクリプト上での
リファレンスは同じオブジェクトを指す。


実際に処理時間に10倍の差が出ているケースがあるが、
Rubyスクリプト上からではその理由を説明できない。


Ruby実行環境内部で行われている処理が原因で処理時間に10倍以上もの差が
生じていると思われる。


処理時間に10倍の差が出ているケースにはGithubで公開している
meteorのテスト中に遭遇した。
0.9.2.3のmeteor.rbの2457行目をコメントにしないでテストした場合、手許の
環境ではコメントにした場合の10倍以上の処理時間となる。
テストスクリプトには

#!bin ruby
# -* coding: UTF-8 -*-

require 'rubygems'
require 'meteor'
#require '../lib/meteor'

pf = Meteor::ParserFactory.build(Meteor::Parser::XML,'sample.xml', 'UTF-8')
ps = pf.parser

start_time = Time.new.to_f

elm1 = ps.element('test','manbo','manbo')
elm3 = ps.element("potato","id","aa")


elm3.attribute('id3','cc')

elm_ = ps.element(elm1)
elm5_ = elm_.child('tech')
10000.times do |i|
  elm_['manbo'] = i.to_s
  elm5 = Meteor::Element.new!(elm5_)
  elm5['mono'] = i.to_s
  elm5.content = i.to_s
  elm_.print
end

ps.print

end_time = Time.new.to_f

puts ps.document

puts '' + (end_time - start_time).to_s + ' sec'

sample.xml

<?xml version="1.0" encoding="UTF-8"?>

<!--
    Document   : test.xml
    Created on : 2008/07/22, 17:32
    Author     : asip
    Description:
        Purpose of the document follows.
-->

<root>

<test manbo="mango" />

<test manbo="manbo">
    <tech mono="mono">こまねち</tech>
</test>
<test manbo="mbo">
    <tech mono="mono">komaneti</tech>
</test>
<test manbo="mbo">
    <tech mono="mono2">komaneti</tech>
</test>
<!-- @quark id="mono" --><!-- /@quark -->
<!-- @quark id="moti" --><!-- /@quark -->
<momo >komaneti</momo>
<kobe momo="mono">komaneti</kobe>
<teo a="aa" b="bb"/>
<mink>komaneti</mink>

<potato id="aa" lc="/cc">
    <potato id="/bb"><test></test></potato>
</potato>

<potato id="aa" id2="bb" lc="/cc">
    <potato id="/bb"><test></test></potato>
</potato>

<potato2 id="aa" id2="bb" lc="/cc"/>

<hamachi id="aa" id2="bb" lc="/cc">
    test
</hamachi>

<hamachi id="aa" id2="bb" />

<kobe momo="mono" value="komaneti" />
<!-- @pp id="cs" -->テスト<!-- /@pp -->

</root>

を用いた。