パスワードを忘れた? アカウント作成
11949955 story
プログラミング

リファクタリングしてもコードの質は改善されないという実験結果 83

ストーリー by hylom
動いているコードは触るなという教訓 部門より
eggy 曰く、

ソースコード中の記述を整理したり、変数名や関数名を分かりやすく書き換えることはリファクタリングと呼ばれているが、実験の結果、リファクタリングを行ったとしてもコードの質が格段に良くなるものでもないことが分かったそうだ(ITWorldSlashdot)。

調査を行ったのはスリランカの研究チーム。リファクタリングによりソフトウェアの品質が外部的・内部的にどれほど向上するのかを調べたそうだ。実験には、オンラインドキュメント評価のスケジューリングおよび管理を行う小規模のアプリケーション(4,500行ほどのC#コード)が用いられ、10個の一般的なリファクタリング技術が適用された。

実験の結果、実際の統計では大きな差はみられなかったもの、参加者らの採点によればリファクタリングされたコードの方が解析性が劣り、コードのバグ修正と実行にはより時間がかかるようになったという。また、リファクタリングしたからといってリソース使用量が減るという結果も得られなかったという。唯一、リファクタリングすることの利点として保守性指数が僅かに高かったものの、品質を測るほかの内部測定では、リファクタリングしたからといってパフォーマンスが上がるわけでもないことが分かったとのこと。

小規模のアプリケーションを用いた実験であるため、この結果に対する懐疑的な見方もあるだろうが、リファクタリングが嫌だと感じている人にとっては、わざわざリファクタリングしないことの十分な理由となるだろうとのこと。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • 正論だな (スコア:4, おもしろおかしい)

    by nim (10479) on 2015年03月05日 23時34分 (#2772703)

    スリランカだけに。

    • by Anonymous Coward

      昔の話だ、今は違うね。

  • 今の一般的なソフトウェアの製作過程でみれば、何らかの問題があるからリファクタリングするのであって、問題の出ていないソースコードに集中的なリファクタリングしても効果が見られないのは当然だという気がする。

    もっとも、地道な研究というのも必要だとは思うし、将来的にはこういう技術の延長でプログラマがまだ気付いていない問題を顕在化する前に知らせるとか取り除いてくれるとかなら嬉しい。

    • by Anonymous Coward on 2015年03月05日 17時42分 (#2772495)

      いやあ、違うんじゃないですかね。
      リファクタリングは「動いているコードを触る」ということであって、基本的に挙動は変化しちゃいかんのですよ。
      挙動が変化するようなものはもはやリファクタリングじゃなく普通の修正です。
      なので、リファクタリングにパフォーマンス向上を求めることが筋違いではないかと。

      ついでに言えば、コンピューターサイエンスの学生に評価をさせたようですけど、学生に「保守性」が本当に認識できるのか、という疑問が……。

      親コメント
      • 問題というとやっぱり、ソフトウェアのバグみたいに聞こえてしまいますね。

        ここで言いたいのは、機能拡張をしたいけれど、既にやっつけの拡張が多数集積していて見通しが悪すぎるとか。そういう問題です。
        それから単純なものだと、ほぼ全ての変数や関数が英数字二文字以内というソースコードは、余程短くない限り問題ありです。
        一息にコーディングするとき余計なことに気を散らしたくないのは判るけれど、関数名がすべて f0 とか f4 とかだったりは受け取れません。

        親コメント
        • by Anonymous Coward

          ここに一票。

          つまり、更なる機能追加の土台均しだから、リファクタリングそのものでコードが複雑になったとしても、その後の機能追加と併せて整合性がとれるなら意味があるはず。

        • by Anonymous Coward

          最後のくだりだけについて反応。
          関数名については 全く同意しますが、
          最近 golang さんとかだと、変数名はなるべく短く、かつすぐ使い終わるように、
          というような方針が推奨されているようですよ。

          • >最近 golang さんとかだと、変数名はなるべく短く、かつすぐ使い終わるように、

            これは変数のスコープは最小にしろ。スコープが十分小さければ変数は短くてもOK。
            っていう、昔から言われていることを言い換えているだけでは。

            親コメント
            • by Anonymous Coward

              昔はスコープ長かったけどね。初期のCは関数の先頭に全部書かなきゃいけなかったし、互換性のために長い間その方式を踏襲してたから。

              むしろ名前の拒否反応は命名規則と習慣からくるんじゃないかな。以前、他人が書いたコードに

              for (int ii = 0; ii < LENGTH; ii++) {

              ってのに手を入れてた時にiiをiにしたくてしょうがなかったもの。頭でわかったつもりになってても、途中から

              「iiってなんだっけ?ああ、ループ回してるんだったな。…(ちょっと先)…ところで、このii*iiってどういう意味だ?あ、あー、ループカウントを2乗してるのか、i * iのことだな。…(さらに先)…あれ、ptrからii引くのはいいけど、このiiってどっから出てきたんだよ。あー、わかった!くそ、思い出した!」

              って感じになったから。jとかkとかnとかlだと全然気にならないんだけど、iiは生理的に受け付けないと自覚してしまった。

      • by Anonymous Coward

        パフのプロジェクトではデバッグと称してリファクタリングしていたパフ

  • by Anonymous Coward on 2015年03月05日 17時20分 (#2772476)

    リファクタリングを考え始める規模がこの実験の10倍程度以上くらいかなというのが、個人的な経験則です。

    みなさんはどれくらい??

    他の方も述べてますが、こういった実験は非常に重要で、定量的に評価される実験が重なることで着実に開発の世界が進歩するのだと思います。
    速度向上を目的とするときも、手を入れる際には必ず計測を行います。リファクタリングにも計測できる手法が開発されたらいいなと思います。

    • by Anonymous Coward

      >みなさんはどれくらい??

      量じゃなくて自分の書くコードから放たれる異臭に耐え切れなくなったら始めてる。
      臭いが我慢できる程度になったら止める。

      機能実装優先で書いた自分のコードの臭いこと臭いこと・・・
      asdf()なんて関数見つけてセルフ悶絶。

    • by Anonymous Coward

      静的チェックしてると、たまに complexity がでかいよ!ってチェックされたりしますよね。
      あれってリファクタリングさぼるんじゃないよ!って意味なのかなと思うのですが。

    • by Anonymous Coward

      理想論で言えば常に。
      即ち、常にリファクタリングがされているので、瞬間瞬間での効果は少なくても構わないと思います。
      リファクタリングして大幅に改善出来る状況って、要はかなり酷い状態ってことでしょ?

  • by Anonymous Coward on 2015年03月05日 17時22分 (#2772478)
    >ソースコード中の記述を整理したり、変数名や関数名を分かりやすく書き換えることはリファクタリングと呼ばれている

    その程度のことをリファクタリングって言うんだっけ?
    • by Patilise (45974) on 2015年03月05日 18時08分 (#2772523)

      リファクタリングはメソッド抽出など大きな変更もあれば、変数名変更のような小さい変更もあります。
      例えばEclipseでは変数名を変えるコマンドがメニューの「リファクタリング」の中に入っている。

      ただ、厳密な定義があるわけではないので、スリランカの研究チームでは変数名変更も含めている、という認識で十分かと。

      親コメント
    • by Anonymous Coward

      なんか根本的に間違えているというか勘違いしている感じよね。

      「新しいソフトウェア作るには、まず既存の似たようなソフトのソースを探してきてCopyright表記をすべて自社名義に書き換える」くらいの斬新さ。

    • by Anonymous Coward

      某漫画ではチ○チ○をいじくりまわすことをリファクタリングと呼んでたぞ

      • by Anonymous Coward

        マイクロでソフトなゲイツのはよく動かないのでリファクタリングしていいの?

  • by Anonymous Coward on 2015年03月05日 17時59分 (#2772515)

    リファクタリング可能なコードはリファクタリング前から既に十分な解析性と変更しやすさを備えている疑惑。
    解析困難で変更困難なコードはリファクタリング困難だろう。
    あとリファクタリングは動作を変える作業ではないから実行時間やリソース使用量が大きく変化されても困る。

  • by Anonymous Coward on 2015年03月05日 17時23分 (#2772479)

    4,500行程度だと、勢いでかける、ちょっと時間かければ全部読んで内容を把握できる、という程度だと思いますので、効果が出づらいのではないでしょうか。

    #とはいえ1か月前に書いた 4500 行のコードは脳 RAM から内容が(ものによっては書いた記憶さえ)消え去っているので、やる意味があるかも。

    • by Anonymous Coward

      だよねぇ、タレコミ元はリファクタリングの意味わかってんのかなという印象。
      リファクタリングはパフォーマンス向上のためにする物でも無いし。
      リファクタリング後の方がコード量増えるのもザラ。
      たかだか4500行程度のコード捏ね繰り回しただけで何寝言言ってんのかと。

      先週自作ドライバのコードをリファクタリングしてたけど主目的は脱臭
      やっつけで書いた処理の書き直しやコピペでできた重複の除去ばっかやってた。
      流石に異臭を放ち始めた食材で調理を続行する気にはなれなかったから。

      #リファクタリング中に仕様変更もしてしまい泥沼になりかけたのはお約束。

  • by Anonymous Coward on 2015年03月05日 17時28分 (#2772483)

    タイトルどおりなんだけど、3段落目の

    リファクタリングされたコードの方が解析性が劣り

    リファクタリングすることの利点として保守性指数が僅かに高かった

    が、矛盾してない?
    俺の思っている保守性とは、また違うものなのかしらん?

    • by Anonymous Coward

      矛盾しないように解釈するなら、コードを理解するコストと、問題発生時に修正するコストの違いじゃねぇの。

    • by Anonymous Coward

      この論文では
      解析性(人間がコードを評価した結果)
      保守性指数(ツールがコードを評価した結果)
      なのでツールは人間の感覚を再現するものではない、ということかと。

      • by Anonymous Coward

        「解析性」は「可読性」と読み替えるとして、
        「バグが出て修正に時間がかかっている」らしい記述からすると、
        リファクタリングに失敗して保守性は低下しているようですから、
        「保守性指数」の算定アルゴリズムが現実の「保守性」を表していないということでしょうか…

    • by Anonymous Coward

      バグが出て修正に時間がかかったのに保守性は改善したとか、いろいろ矛盾していますね。

      可能性
      ・統計情報を適切に読み解けてない
      ・記事(あるいは翻訳)が傾向と事例を区別できていない
      ・まともにできる人がいなくて、「失敗することが多かった」と言っているだけ
        :

    • by Anonymous Coward

      元の論文を読めばわかることだけど、適用したリファクタリングは以下のようなもの。特にR3~R6を無分別に適用したせいで、コーディングのミスや漏れを防げるようになった代わりに、処理の具体的内容が読みづらくなったということだと思う。

      Selected Refactoring Techniques are:

      R1- Introduce Local Extension
      R2- Duplicate Observed Data
      R3- Replace Type Code with Subclasses
      R4- Replace Type Code with State/Strategy
      R5- Replace Conditional with Polymorphism
      R6- Introduce Null Object
      R7- Extract

      • リファクタリングには必ず逆操作が存在するはずだから、良い結果になる操作と悪い結果になる操作がある。
        その操作を個々の状況、条件から適切なものを選んで適用するのがリファクタリングなんだから、無分別に適用したらリファクタリングじゃない。
        親コメント
  • by Anonymous Coward on 2015年03月05日 17時38分 (#2772489)

    これ、変更前 変更後のソース見せてもらえないとなんとも言えないよね?
    そもそもリファクタリングの定義ってナニ?

  • by Anonymous Coward on 2015年03月05日 17時45分 (#2772498)

    そうか、そうか、つまり君はそういうやつなんだな。>hylom

    • by Anonymous Coward

      ビルゲイツが言ったことで有名なフレーズなんですがそれは

      • by Anonymous Coward

        ゲイツが言うからリファクタリングは不要ってことですね、わかります

    • by Anonymous Coward

      hylomがどうであれ、こういうもの言いをする奴って、そういう奴だよな。

      http://ja.m.wikipedia.org/wiki/ [wikipedia.org]人身攻撃

  • by Anonymous Coward on 2015年03月05日 17時46分 (#2772500)

    >パフォーマンスが上がるわけでもないことが分かったとのこと。

    代表的な10の方法ってものが、Wikipediaのリファクタリングの項目にのっているものだとすると、
    そもそもパフォーマンスが向上するような手法は無いと思うのですけど。

    あくまで保守性を上げるぐらいでしょう。

    • by Anonymous Coward

      むしろ、関数が分割されて呼び出しコストがかかりそう...

      • ある分野においてはそうかもしれないけど、PC用のアプリケーションなら小さい関数に分割することで速くなることも多い。逆にインライン化して「確実に」速くなるのはアクセサ相当のものぐらい。

        もちろん、「小さい処理」であれば速くなるだろうけど、その「小さい処理」の線引きが難しいから、関数に関しては可読性重視で書いておくのがいい。高速化のテクニックはいろいろあるけど、呼び出す関数が静的に決定できる限りにおいては、簡素になる方向で書いておけば、ほぼ間違いはない。

        そもそも、高速化が必要なのかと言うのも問題だし、高速化するにしても、関数呼び出しにかかわる部分をいじるのは割と後の方。まずは余計な重い処理を減らすことが先決で、そういう処理を探し出すためにも長い関数は分割しておいた方がいい。

        親コメント
      • by Anonymous Coward

        実験データが4500行のコードといっているので、
        分割されても複数箇所から呼び出されることも無さそうですね。

        そもそもタイトルにある「コードの質」って何をもっていっているのだろうか。
        コードの質が高い≒パフォーマンスでしょう。

    • by Anonymous Coward

      そうそう。 ソースにドキュメントを書き入れるのもリファクタリングだよね?
      関数の機能を確認し、インターフェース(引数と戻り値と大域変数との関わりなど)を
      詳細に説明する説明文をコメントとして入れる。 各処理のコメントも充実させるなどな。

  • by Anonymous Coward on 2015年03月05日 18時05分 (#2772519)

    - http://arxiv.org/ftp/arxiv/papers/1502/1502.03526.pdf [arxiv.org]

    3.1で「先行研究で高いインパクトがあった10リファクタリング手法を使いました」的なことがあり、
    このリストの10個のほとんどがコード(とくにclass)を増やすリファクタリングである以上、
    リファクタリング手法の適用によって評価指標が下がるのは当然なのでは。

    リファクタリングする/しないの後に、関連する部分にコードを追加したり単純化したりしたものを
    評価したら、だいぶ違ってくるのではないでしょうか。

    • by Anonymous Coward

      この論文自体は、2にあるように先行研究が欠いたことを補完することが主な動機であり、
      結論も、未熟者がやろうがリファクタリングそれ自体が効果がある、というものではないよね、的な話でした。

      タレコミの元になったメディア記事のように拡大解釈して、
      リファクタリング活動そのものをDISるようなものではないと思います。

  • by Anonymous Coward on 2015年03月05日 18時22分 (#2772532)

    リファクタしようと言う気力すらなくなるソースコードがこれで正当化されそうだ

  • by Anonymous Coward on 2015年03月05日 18時48分 (#2772557)

    「パフォーマンス=性能」の主語を勘違いしていませんか?

    この記事に登場するパフォーマンスの主語はすべて「保守性」であって、
    実行速度等のプログラムのブラックボックスな意味のパフォーマンスではないと思われます。

    # リファクタリングの主旨を理解していればミスリードしない、はず?
    # 理解を先回りして訳ができるというのは、実際翻訳を体験してみると難しさがわかります。

    • by Anonymous Coward

      >唯一、リファクタリングすることの利点として保守性指数が僅かに高かったものの、品質を測るほかの内部測定では、リファクタリングしたからといってパフォーマンスが上がるわけでもないことが分かったとのこと
      ここにパフォーマンスという言葉が出てきて保守性指数がわずかに高いのにパフォーマンスが上がるわけでもないと言っているので、「保守性」ではなく「(コードの)品質」では?

      • by Anonymous Coward

        品質ならQualityを使いそうだけどなぁ...

        • by Anonymous Coward

          ずばり

          > Refactoring code doesn’t make it run faster

          と書いてあるパフ

          > Internal measure of software quality were calculated for the refactored and un-refactored code using Visual Studio. These metrics were: Maintainability Index, Cyclomatic Complexity, Depth of Inheritance, Class Coupling, and Line of Code.

          品質は速度とぜんぜん関係ないパフ
          eggyはなぜくっつけたのか理解に苦しむパフ

typodupeerror

未知のハックに一心不乱に取り組んだ結果、私は自然の法則を変えてしまった -- あるハッカー

読み込み中...