Что могло бы вызвать большие издержки совершения звонка HttpWebRequest?

Когда я отправляю/получаю использованию данных HttpWebRequest (на Silverlight) в маленьких блоках, я измеряю очень маленькую пропускную способность 500 байтов/с по "localhost" соединению. При отправке данных в больших блоках я получаю 2 МБ/с, который приблизительно в 5000 раз быстрее.

Кто-либо знает то, что могло вызвать эти невероятно большие издержки?

Дополнительная информация:

  • Я использую метод POST HTTP
  • Я сделал измерение производительности и на Firefox 3.6 и на Internet Explorer 7. Оба показали подобные результаты.
  • Мой ЦП загружается только для 10% (четырехъядерный, так 40% на самом деле)
  • WebClient показал подобные результаты
  • WCF/SOAP показал подобные результаты

Обновление: Silverlight клиентский код, который я использую, является по существу моей собственной реализацией класса WebClient. Причина, которую я записал этому, состоит в том, потому что я заметил ту же проблему производительности с WebClient, и я думал, что HttpWebRequest позволит настраивать проблему производительности. К сожалению, это не работало. Реализация следующие:

public class HttpCommChannel
{
    public delegate void ResponseArrivedCallback(object requestContext, BinaryDataBuffer response);

    public HttpCommChannel(ResponseArrivedCallback responseArrivedCallback)
    {
        this.responseArrivedCallback = responseArrivedCallback;
        this.requestSentEvent = new ManualResetEvent(false);
        this.responseArrivedEvent = new ManualResetEvent(true);
    }

    public void MakeRequest(object requestContext, string url, BinaryDataBuffer requestPacket)
    {
        responseArrivedEvent.WaitOne();
        responseArrivedEvent.Reset();

        this.requestMsg = requestPacket;
        this.requestContext = requestContext;

        this.webRequest = WebRequest.Create(url) as HttpWebRequest;
        this.webRequest.AllowReadStreamBuffering = true;
        this.webRequest.ContentType = "text/plain";
        this.webRequest.Method = "POST";

        this.webRequest.BeginGetRequestStream(new AsyncCallback(this.GetRequestStreamCallback), null);
        this.requestSentEvent.WaitOne();
    }

    void GetRequestStreamCallback(IAsyncResult asynchronousResult)
    {
        System.IO.Stream postStream = webRequest.EndGetRequestStream(asynchronousResult);

        postStream.Write(requestMsg.Data, 0, (int)requestMsg.Size);
        postStream.Close();

        requestSentEvent.Set();
        webRequest.BeginGetResponse(new AsyncCallback(this.GetResponseCallback), null);
    }

    void GetResponseCallback(IAsyncResult asynchronousResult)
    {
        HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult);
        Stream streamResponse = response.GetResponseStream();
        Dim.Ensure(streamResponse.CanRead);
        byte[] readData = new byte[streamResponse.Length];
        Dim.Ensure(streamResponse.Read(readData, 0, (int)streamResponse.Length) == streamResponse.Length);
        streamResponse.Close();
        response.Close();

        webRequest = null;
        responseArrivedEvent.Set();
        responseArrivedCallback(requestContext, new BinaryDataBuffer(readData));
    }

    HttpWebRequest webRequest;
    ManualResetEvent requestSentEvent;
    BinaryDataBuffer requestMsg;
    object requestContext;
    ManualResetEvent responseArrivedEvent;
    ResponseArrivedCallback responseArrivedCallback;
}

Я использую этот код для отправки данных назад и вперед в сервер HTTP.

Обновление: после обширного исследования я прихожу к заключению, что проблема производительности свойственна к Silverlight v3.

5
задан Community 23 May 2017 в 12:26
поделиться

3 ответа

Вполне возможно, вы наблюдаете эффекты алгоритма Нагла, попробуйте:

this.webRequest.UseNagleAlgorithm.ServicePoint = false;

Также, "рукопожатие" Expect100Continue имеет отношение к производительности вызова мыльного сервиса:

this.webRequest.Expect100Continue.ServicePoint = false;

UDPATE:

Только что понял, что ServicePoint недоступен в Compact Framework. Однако вы можете доказать это, сделав:

ServicePointManager.UseNagleAlgorithm = false

Или изменив соответствующую настройку в конфигурационном файле приложения, или что там у вас в silverlight?

.
4
ответ дан 14 December 2019 в 13:33
поделиться

Как упомянул Майк Диммик в своем ответе, проблема с задержкой может вызвать проблемы, однако, помимо проблем с задержкой в ​​случае очень малых полезных данных, выделение поток для выполнения (даже с пулом потоков) с последующим установлением соединения будет составлять гораздо больший процент от общего затраченного времени, чем при массовом маршруте полезной нагрузки.

1
ответ дан 14 December 2019 в 13:33
поделиться

Я подозреваю, что ваша проблема просто в задержке. Любому сообщению требуется некоторое время, чтобы добраться до сервера, чтобы оно было проанализировано, обработано и сгенерировано ответ, а ответу требуется некоторое время, чтобы вернуться к клиенту и преобразовать его в пригодный для использования ответ. В вашей производительности, скорее всего, будет преобладать время прохождения туда и обратно.

По сути, любой интерфейс, пересекающий границу взаимодействия - будь то межпроцессный или межмашинный - должен быть «коротким», а не «болтливым». Отправляйте как можно больше информации в каждом запросе и получайте как можно больше данных в ответ. Это может показаться тривиальным на той же машине, но я увидел десятикратное улучшение производительности на сервере приложений за счет пакетирования команд в рабочем процессе, вместо того, чтобы выполнять обратный вызов из рабочего процесса в процесс главного сервера для каждой команды.

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

1
ответ дан 14 December 2019 в 13:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: