0

How can I optimize this code snippet?

string page = wc.DownloadString("https://www.youtube.com/browse_ajax?action_continuation=1&continuation=4qmFsgI8EhhVQ2ZXdHFQeUJNR183aTMzT2VlTnNaWncaIEVnWjJhV1JsYjNNZ0FEQUJPQUZnQVdvQWVnRTB1QUVB");
int pos;
while ((pos = page.IndexOf("/watch?v=")) > 0) {
    page = page.Substring(pos);
    page = page.Substring(page.IndexOf("video-time"));
    page = page.Substring(page.IndexOf("aria-label"));
    page = page.Substring(page.IndexOf(@"\u003e") + 6);
    string vt = page.Substring(0, page.IndexOf(@"\u003c"));
    page = page.Substring(page.IndexOf("title=") + 1);
    page = page.Substring(page.IndexOf("title=") + 1);
    page = page.Substring(page.IndexOf("title=") + 1);
    page = page.Substring(page.IndexOf("\\\"") + 2);
    string tt = page.Substring(0, page.IndexOf("\\\"  aria-describedby="));
}

Sadly, I can't just skip some of the Substring lines as this seems to be the only way to find the right occurance of vt and tt. Since Substring always returns a new string I tried a solution with StringBuilder:

System.Text.StringBuilder sb=new System.Text.StringBuilder(wc.DownloadString("https://www.youtube.com/browse_ajax?action_continuation=1&continuation=4qmFsgI8EhhVQ2ZXdHFQeUJNR183aTMzT2VlTnNaWncaIEVnWjJhV1JsYjNNZ0FEQUJPQUZnQVdvQWVnRTB1QUVB"));
int pos;
while ((pos = sb.ToString().IndexOf("/watch?v=")) > 0) {
    sb.Remove(0,pos);
    sb.Remove(0,sb.ToString().IndexOf("video-time"));
    sb.Remove(0,sb.ToString().IndexOf("aria-label"));
    sb.Remove(0,sb.ToString().IndexOf(@"\u003e") + 6);
    string vt =sb.ToString(0,sb.ToString().IndexOf(@"\u003c"));
    sb.Remove(0,sb.ToString().IndexOf("title=") + 1);
    sb.Remove(0,sb.ToString().IndexOf("title=") + 1);
    sb.Remove(0,sb.ToString().IndexOf("title=") + 1);
    sb.Remove(0,sb.ToString().IndexOf("\\\"") + 2);
    string tt =sb.ToString(0,sb.ToString().IndexOf("\\\"  aria-describedby="));
}

I was suprised to find out that this solution, although it doesn't look like due to all the ToString(), is indeed slightly faster.

Now, is there a way to optimize this even further? Maybe even make it look better?

  • 2
    You *can* skip those `SubString`s, `IndexOf` can take a starting position so you can just move the position instead of copying most of the string. – harold Jul 02 '17 at 21:45
  • However then I have to define the starting position by using another IndexOf, as I have no idea where `vt` and `tt` begin. That basically restructures everything, making it an unreadable one liner, but I doubt it makes it more efficient or looking better –  Jul 02 '17 at 21:48
  • You don't have to write it as a one-liner of course. Just update a position with `IndexOf`, and then use that as the starting position in the next `IndexOf` and so on until you reach the target – harold Jul 02 '17 at 21:52
  • Rather than making all those `ToString()` calls, you could use the `IndexOf()` extension method for `StringBuilder` from [this answer](https://stackoverflow.com/a/6601226/3744182). – dbc Jul 02 '17 at 22:04
  • ... Or this one: [Fastest search method in StringBuilder](https://stackoverflow.com/a/12261971/3744182). – dbc Jul 02 '17 at 22:15

2 Answers2

0

As suggested by @harold

string page = wc.DownloadString("https://www.youtube.com/browse_ajax?action_continuation=1&continuation=4qmFsgI8EhhVQ2ZXdHFQeUJNR183aTMzT2VlTnNaWncaIEVnWjJhV1JsYjNNZ0FEQUJPQUZnQVdvQWVnRTB1QUVB");
int pos;
while ((pos = page.IndexOf("/watch?v=")) > 0) {
    int subPos=pos;
    subPos=page.IndexOf("video-time",subPos);
    subPos=page.IndexOf("aria-label",subPos);
    subPos=page.IndexOf(@"\u003e",subPos);
    subPos+=6;
    string vt=page.Substring(subPos,(subPos=page.IndexOf(@"\u003c",subPos)));
    subPos=page.IndexOf("title=",subPos);
    subPos++;
    subPos=page.IndexOf("title=",subPos);
    subPos++;
    subPos=page.IndexOf("title=",subPos);
    subPos=page.IndexOf("\\\"",subPos);
    subPos+=2;
    string tt=page.Substring(subPos,(subPos=page.IndexOf("\\\"  aria-describedby=", subPos)));
    page=page.Substring(subPos);
}

Seems to be quite a lot faster than using StringBuilder with ToString()

0

As suggested by @dbc, using these extension methods

System.Text.StringBuilder sb=new System.Text.StringBuilder(wc.DownloadString("https://www.youtube.com/browse_ajax?action_continuation=1&continuation=4qmFsgI8EhhVQ2ZXdHFQeUJNR183aTMzT2VlTnNaWncaIEVnWjJhV1JsYjNNZ0FEQUJPQUZnQVdvQWVnRTB1QUVB"));
int pos;
while ((pos = sb.ToString().IndexOf("/watch?v=")) > 0) {
    sb.Remove(0,pos);
    sb.Remove(0,sb.IndexOf("video-time"));
    sb.Remove(0,sb.IndexOf("aria-label"));
    sb.Remove(0,sb.IndexOf(@"\u003e") + 6);
    string vt =sb.ToString(0,sb.IndexOf(@"\u003c"));
    sb.Remove(0,sb.IndexOf("title=") + 1);
    sb.Remove(0,sb.IndexOf("title=") + 1);
    sb.Remove(0,sb.IndexOf("title=") + 1);
    sb.Remove(0,sb.IndexOf("\\\"") + 2);
    string tt =sb.ToString(0,sb.IndexOf("\\\"  aria-describedby="));
}

Should be faster than using StringBuilder with ToString(), my test results are a bit jerky here.