Производительность HttpWebRequest с использованием POST - PullRequest
2 голосов
/ 06 января 2009

У меня есть небольшой инструмент, который я использую для тестирования веб-сервиса.

Он может вызывать веб-сервис, используя POST или GET.

Код для использования POST:

public void PerformRequest()
{
  WebRequest webRequest = WebRequest.Create(_uri);

  webRequest.ContentType = "application/ocsp-request";
  webRequest.Method = "POST";
  webRequest.Credentials = _credentials;
  webRequest.ContentLength = _request.Length;
  ((HttpWebRequest)webRequest).KeepAlive = false;

  using (Stream st = webRequest.GetRequestStream())
    st.Write(_request, 0, _request.Length);

  using (HttpWebResponse httpWebResponse = (HttpWebResponse)webRequest.GetResponse())
  using (Stream responseStream = httpWebResponse.GetResponseStream())
  using (BufferedStream bufferedStream = new BufferedStream(responseStream))
  using (BinaryReader reader = new BinaryReader(bufferedStream))
  {
    if (httpWebResponse.StatusCode != HttpStatusCode.OK)
      throw new WebException("Got response status code: " + httpWebResponse.StatusCode);

    byte[] response = reader.ReadBytes((int)httpWebResponse.ContentLength);
    httpWebResponse.Close();
  }      
}

Код для использования GET:

protected override void PerformRequest()
{
  WebRequest webRequest = WebRequest.Create(_uri + "/" + Convert.ToBase64String(_request));

  webRequest.Method = "GET";
  webRequest.Credentials = _credentials;
  ((HttpWebRequest)webRequest).KeepAlive = false;

  using (HttpWebResponse httpWebResponse = (HttpWebResponse)webRequest.GetResponse())
  using (Stream responseStream = httpWebResponse.GetResponseStream())
  using (BufferedStream bufferedStream = new BufferedStream(responseStream))
  using (BinaryReader reader = new BinaryReader(bufferedStream))
  {
    if (httpWebResponse.StatusCode != HttpStatusCode.OK)
      throw new WebException("Got response status code: " + httpWebResponse.StatusCode);

    byte[] response = reader.ReadBytes((int)httpWebResponse.ContentLength);
    httpWebResponse.Close();
  }
}

Как видите, код очень похож. Во всяком случае, я ожидал бы, что GET-метод будет немного медленнее, поскольку он должен кодировать и передавать данные в Base64.

Но когда я запускаю его, я вижу, что POST-метод использует гораздо больше вычислительной мощности, чем GET-метод. На моей машине я могу запустить 80 потоков GET-метода, используя приблизительно 5% ЦП, в то время как 80 потоков POST-метода использует 95% ЦП.

Есть ли что-то более дорогое в использовании POST? Что я могу сделать, чтобы оптимизировать POST-метод? Я не могу повторно использовать соединение, так как хочу симулировать запросы от разных клиентов.

dotTrace сообщает, что 65% времени обработки тратится в webRequest.GetResponse () при использовании POST.

Базовый веб-сервис использует дайджест-аутентификацию, если это имеет какое-либо значение.

1 Ответ

3 голосов
/ 06 января 2009

Ну, в зависимости от сложности окончательного URI, может быть, что "GET" запросы кэшируются? «POST» не кэшируется по умолчанию, но часто «GET» (как и должно быть идемпотентно). Вы пытались понюхать, чтобы увидеть, есть ли здесь какая-то разница?

Также - вы можете найти WebClient более простым в использовании - что-то вроде:

using (WebClient wc = new WebClient())
{
    byte[] fromGet = wc.DownloadData(uriWithData);
    byte[] fromPost = wc.UploadData(uri, data);
}
...