文字列クラスの効率

今、C++ で文字列を表すクラスを書いているんだけど、とりあえずインターフェースとして C# の String クラスを真似してたりする。


そこで気付いたんだけれど、例えば、C# の IndexOf は複数の定義があって、その中に、

public int IndexOf( String value );
public int IndexOf( String value , int startIndex );
public int IndexOf( String value , int startIndex , int count );

こういう定義があったりする。


この時、IndexOf( String , int , int ) さえ実装しておけば、

int IndexOf( String value ){
    return IndexOf( value , 0 );
}
int IndexOf( String value , int startIndex ){
    return IndexOf( value , startIndex , Length() - startIndex );
}

これでいいと思うかもしれないけれども、効率を考えた場合、これはあまり良くない。
なぜかというと、IndexOf( String , int , int ) は次のように定義されているからだ。

int IndexOf( String value , int startIndex , int count ){
    if( value == null ){
        throw ぬるぽ
    }
    if( count < 0 ||
        startIndex < 0 ||
        startIndex + count > Length() ){
            throw 引数不正
    }
    // あとは通常の処理
}

IndexOf( String , int ) から IndexOf( String , int , int ) を呼び出した場合、startIndex が負の値でなくて Length() を超えていないことが分かれば count が負の値にならず、startIndex + count が Length() を超えないことは分かる。count のチェックは無駄だ。
そして、IndexOf( String ) から IndexOf( String , int ) を呼び出した場合は、startIndex をチェックする必要すらない。
つまり、無駄なエラー処理を行っているのだ。


なので、以下のようにしてやるのがいいと思う。

int IndexOf( String value ){
    if( value == null ){
        throw ぬるぽ
    }
    return _IndexOf( value , 0 , value.Length() );
}
int IndexOf( String value , int startIndex ){
    if( value == null ){
        throw ぬるぽ
    }
    if( startIndex < 0 ||
        startIndex > Length() ){
            throw 引数不正
    }
    return _IndexOf( value , startIndex , Length() - startIndex );
}
int IndexOf( String value , int startIndex , int count ){
    if( value == null ){
        throw ぬるぽ
    }
    if( count < 0 ||
        startIndex < 0 ||
        startIndex + count > Length() ){
            throw 引数不正
    }
    return _IndexOf( value , startIndex , count );
}
int _IndexOf( String value , int startIndex , int count ){
    // エラーはないものとして処理を行う
}

まあ、そうは言ってもこの程度なら無視出来るオーダーだろうし、そんな気にしなくて良いのかもしれない。
けれども、この無駄に気付く人と気付かない人とでは、かなりの差があるような気がする。