Чтение из сокета 1 байт во время по сравнению с чтением в большом блоке

У меня та же ошибка, когда я пытаюсь вставить java BasicDBObject в коллекцию MongoDb.

Мой объект создан из Xml, преобразованного в Json.

java.lang.IllegalArgumentException: can't serialize class net.sf.json.JSONNull
    at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:299)
    at org.bson.BasicBSONEncoder.putMap(BasicBSONEncoder.java:339)
    at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:261)

Эта ошибка вызвана пустыми тегами в Xml; когда я удалил все пустые теги, я решил это.

6
задан green_t 31 May 2009 в 10:12
поделиться

7 ответов

Если вы читаете прямо из сокета, а не из промежуточное представление более высокого уровня, которое может быть буферизовано, тогда, без всяких сомнений, лучше полностью прочитать 1024 байта, поместить их в ОЗУ в буфер, а затем проанализировать данные из ОЗУ.

Почему? Чтение сокета - это системный вызов, который вызывает переключение контекста при каждом чтении, что дорого. Подробнее об этом: IBM Tech Lib: Повышение производительности сокетов

4
ответ дан 8 December 2019 в 18:41
поделиться

Первое и самое простое:

cin.getline(buffer,1024);

Во-вторых, обычно весь ввод-вывод буферизуется, поэтому вам не нужно особо беспокоиться

В-третьих, запуск процесса CGI обычно стоит намного дороже, чем обработка ввода ( если он не огромный файл) ... Так что вы можете просто не думать об этом.

1
ответ дан 8 December 2019 в 18:41
поделиться

Я не могу комментировать C ++, но с других платформ - да, это может иметь большую разницу; особенно в отношении количества переключений, которые должен выполнить код, и количества раз, когда ему нужно беспокоиться об асинхронной природе потоков и т. д.

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

5
ответ дан 8 December 2019 в 18:41
поделиться

G'day,

One of the big performance hits by doing it one byte at a time is that your context is going from user time into system time over and over. And over. Not efficient at all.

Grabbing one big chunk, typically up to an MTU size, is measurably more efficient.

Why not scan the content into a vector and iterate over that looking out for \n's to separate your input into lines of web input?

HTH

cheers,

1
ответ дан 8 December 2019 в 18:41
поделиться

Вы не читаете по одному байту из сокета, вы читаете по одному байту из системы ввода-вывода C / C ++, которая, если вы используете CGI, уже будет иметь буферизовал весь ввод из сокета. Вся суть буферизованного ввода-вывода состоит в том, чтобы сделать данные доступными для программиста таким образом, чтобы они были удобны для обработки, поэтому, если вы хотите обрабатывать один байт за раз, продолжайте.

Edit: ] Поразмыслив, из вашего вопроса неясно, внедряете ли вы CGI или просто используете его. Вы можете прояснить это, разместив фрагмент кода, который указывает, как вы в настоящее время читаете этот единственный байт.

Если вы читаете сокет напрямую, вам следует просто прочитать весь ответ на GET в буфер, а затем обработать его. Это дает множество преимуществ, включая производительность и простоту кодирования.

Если вы привязаны к небольшому буферу, используйте классические алгоритмы буферизации, например:

getbyte:
   if buffer is empty
      fill buffer
      set buffer pointer to start of buffer
   end
   get byte at buffer pointer
   increment pointer
1
ответ дан 8 December 2019 в 18:41
поделиться

Вы можете открыть дескриптор файла сокета с помощью функции fdopen (). Затем вы буферизовали ввод-вывод, чтобы вы могли вызвать fgets () или аналогичный для этого дескриптора.

1
ответ дан 8 December 2019 в 18:41
поделиться

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

0
ответ дан 8 December 2019 в 18:41
поделиться