235. Lowest Common Ancestor of a Binary Search Tree#10
235. Lowest Common Ancestor of a Binary Search Tree#10
Conversation
| * > まず、原理的に、コンピュータがコードが到達可能か不可能かを判定することは不可能です。これはチューリングマシンの停止性問題は判定できないことからいえます。一方で、Java や Rust などは、コンパイル時に型のチェックを真面目にしていて、到達不能なコードかはある程度判定します。しかし、不完全です。このため、正確に考えると到達不可能な箇所であったとしても、コンパイラには分からない場合が多々あります。こういったときに、そこの行に例外を書くことでコンパイル可能になります。何を言っているかというと、上のような事情ならば、例外を書くのはいいですが、そうでなければ、私はデッドコードは基本的に書かないほうがよいと思っています。(せいぜいコメントでいいでしょう。) | ||
| * 結局 `std::unreachable` はありなのかな?個人的には無限ループより良さそうに思うのだけど…。 | ||
| * あ、これめっちゃ新しい (C++23)。なるほどそれ以前の環境を考えると無限ループなどが選択肢に入ってくるのか。 | ||
| * 例外はなんか重いから C++ ではあまり使わないというのも聞いたことがある。 |
There was a problem hiding this comment.
「例外は重い」というのは、return と比べれば重いです。
ここをみると char++ * 100万回が 4 ms で、3906回の exception で1秒くらいかかっています。200マイクロ秒かかるということですね。
https://stackoverflow.com/questions/13835817/are-exceptions-in-c-really-slow
私の直感よりもだいぶ遅いのですが、Exception オブジェクトを作ってスタックを巻き戻しながら誰がキャッチするかを探すということになるので、かなり遅いことは確かです。
ただ、Google 社内で使わない理由は、それよりも大域脱出なのでコードが追えなくなるほうが大きいと私は思っています。Chrome の C++ ソースコードは数万ファイルありますから、読んでいて例外が投げてあったら行き先探すのが辛いですね。
There was a problem hiding this comment.
自分が英語をちゃんと読めている自信がないのですが、スタイルガイドには「スクラッチからやり始めなければならないとしたら、選択は変わってくるかもしれない。」といった文言が書いてあります。参考まで。
https://google.github.io/styleguide/cppguide.html#Exceptions
Our advice against using exceptions is not predicated on philosophical or moral grounds, but practical ones. Because we'd like to use our open-source projects at Google and it's difficult to do so if those projects use exceptions, we need to advise against exceptions in Google open-source projects as well. Things would probably be different if we had to do it all over again from scratch.
There was a problem hiding this comment.
Exception オブジェクトを作ってスタックを巻き戻しながら誰がキャッチするかを探すということになるので、かなり遅いことは確かです。
Exception が (原理的に) なぜ遅いのか、というのを考えたことがありませんでした。なるほど。
大域脱出なのでコードが追えなくなるほうが大きいと私は思っています。Chrome の C++ ソースコードは数万ファイルありますから、読んでいて例外が投げてあったら行き先探すのが辛いですね。
なるほど、確かにこれは辛いですね。
しかしこうした点は C++ 以外の言語 (Java や Python など) ではそこまで忌避されていないように思います。Java はわかりませんが Python だと例外を返すのはごく普通のことだと思うのですが、それはどういった差があるのでしょう…?
There was a problem hiding this comment.
@nodchip さんが引用くださったスタイルガイドなんかを参照していると、「思いから使うな」というよりは、「まあ多少重いのは重いんだけどそれ自体は許容範囲で、どちらかというと大規模コードベースを前提にした時の不都合が大きくなるから使うな」という気がしました。
そういう論理であれば、小さいプロジェクトであれば普通に使ってよい気もしましたが、初心者なのでそのあたりの感覚はずれているかもしれません。。
There was a problem hiding this comment.
Java や Python はガーベージコレクションがあるのでスタックの解析が不要で、言語がそもそも遅いのです。あと、言語仕様上書かざるを得ないです。
「まあ多少重いのは重いんだけどそれ自体は許容範囲で、どちらかというと大規模コードベースを前提にした時の不都合が大きくなるから使うな」
だいたいそう思います。あと Google 社内はそれを前提として環境構築(例えばコードサーチからして)しているので、不利益は大きくなります。
| * > まず、原理的に、コンピュータがコードが到達可能か不可能かを判定することは不可能です。これはチューリングマシンの停止性問題は判定できないことからいえます。一方で、Java や Rust などは、コンパイル時に型のチェックを真面目にしていて、到達不能なコードかはある程度判定します。しかし、不完全です。このため、正確に考えると到達不可能な箇所であったとしても、コンパイラには分からない場合が多々あります。こういったときに、そこの行に例外を書くことでコンパイル可能になります。何を言っているかというと、上のような事情ならば、例外を書くのはいいですが、そうでなければ、私はデッドコードは基本的に書かないほうがよいと思っています。(せいぜいコメントでいいでしょう。) | ||
| * 結局 `std::unreachable` はありなのかな?個人的には無限ループより良さそうに思うのだけど…。 | ||
| * あ、これめっちゃ新しい (C++23)。なるほどそれ以前の環境を考えると無限ループなどが選択肢に入ってくるのか。 | ||
| * 例外はなんか重いから C++ ではあまり使わないというのも聞いたことがある。 |
There was a problem hiding this comment.
自分が英語をちゃんと読めている自信がないのですが、スタイルガイドには「スクラッチからやり始めなければならないとしたら、選択は変わってくるかもしれない。」といった文言が書いてあります。参考まで。
https://google.github.io/styleguide/cppguide.html#Exceptions
Our advice against using exceptions is not predicated on philosophical or moral grounds, but practical ones. Because we'd like to use our open-source projects at Google and it's difficult to do so if those projects use exceptions, we need to advise against exceptions in Google open-source projects as well. Things would probably be different if we had to do it all over again from scratch.
| TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { | ||
| int p_val = p->val; | ||
| int q_val = q->val; | ||
| std::stack<TreeNode*> nodes; |
There was a problem hiding this comment.
nodes には高々 1 個までしか要素が詰まれないため、単に TreeNode* で良いように思いました。
There was a problem hiding this comment.
これ気づいていませんでした。stack で積んでいく、とぃうよりは単一の node を動かして走査している、と理解すべきでした。
235. Lowest Common Ancestor of a Binary Search Tree
https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/