Преобразуйте байт ASCII [] для Строкового представления

Я пытаюсь передать байт [] содержащий символы ASCII к log4j, быть зарегистрированным в файл с помощью очевидного представления. Когда я просто передаю в byt [], его, конечно, рассматривают как объект, и журналы довольно бесполезны. Когда я пытаюсь преобразовать их в строковое использование new String(byte[] data), производительность моего приложения разделена на два.

Как я могу эффективно передать их в, не подвергаясь приблизительно 30us штраф времени преобразования их к строкам.

Кроме того, почему это занимает много времени для преобразования их?

Спасибо.

Править

Я должен добавить, что я - optmising для задержки здесь - и да, 30us действительно имеет значение! Кроме того, эти массивы варьируются от ~100 полностью до нескольких тысяч байтов.

19
задан jwoolard 4 February 2010 в 18:27
поделиться

5 ответов

Вы хотите отложить обработку массива byte[] до тех пор, пока log4j не решит, что он действительно хочет записать сообщение в журнал. Таким образом, вы можете записать его в журнал на уровне DEBUG, например, при тестировании, а затем отключить в процессе производства. Например, вы можете:

final byte[] myArray = ...;
Logger.getLogger(MyClass.class).debug(new Object() {
    @Override public String toString() {
        return new String(myArray);
    }
});

Теперь вы не будете платить штраф за скорость, пока не занесете данные в журнал, потому что метод toString не будет вызван, пока log4j не решит, что он действительно хочет занести сообщение в журнал!

Теперь я не уверен, что вы имеете в виду под "очевидным представлением", поэтому я предположил, что вы имеете в виду преобразование в строку, переинтерпретируя байты как кодировку по умолчанию. Теперь, если Вы имеете дело с двоичными данными, это очевидно бесполезно. В этом случае я бы предложил использовать Arrays.toString(byte[]) для создания отформатированной строки вдоль строк

[54, 23, 65, ...]
14
ответ дан 30 November 2019 в 03:16
поделиться

В случаях, аналогичных примеру, можно фактически объединить вариант 1 с одним из других вариантов: Опустите предупреждение по умолчанию и включите соответствующее предупреждение компилятора, если оно доступно. Таким образом, можно сразу выяснить, добавляется ли новое перечисляемое значение, и можно удобно добавить обращение, не гарантируя выполнение определенного пути кода для его поиска во время выполнения.

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

-121--1855977-

Попробуйте это:

Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
startActivity(browserIntent);

Это работает хорошо для меня.

Что касается отсутствующего «http ://» Я бы просто сделал что-то подобное:

if (!url.startsWith("http://") && !url.startsWith("https://"))
   url = "http://" + url;

Я бы также, вероятно, предварительно заполнил ваш Edit Text, что пользователь вводит URL с« http ://».

-121--1754023-

Снижение производительности в два раза? Насколько велик этот массив байтов? Если это, например, 1MB, то, безусловно, есть больше факторов, чтобы принять во внимание, чем просто «преобразование» из байтов в символы (который должен быть достаточно быстрым, хотя). Запись 1MB данных вместо «всего» 100 байт (которые может генерировать байт [] .toString () ) в файл журнала , очевидно, займет некоторое время. Файловая система диска работает не так быстро, как память ОЗУ.

Необходимо изменить строковое представление массива байтов. Может быть, с некоторой более конфиденциальной информацией, например, имя, связанное с ним (имя файла?), его длина и так далее. В конце концов, что этот массив байт на самом деле представляет?

Изменить : Я не могу вспомнить, что я видел «приблизительно 30us» фраза в вашем вопросе, может быть, вы отредактировали его в течение 5 минут после запроса, но это на самом деле микрооптимизация и это, конечно, не должно вызвать «вдвое исполнение» в целом. Если вы не пишете их миллион раз в секунду (тогда почему вы хотите это сделать? вы не злоупотребляете феноменом «лесозаготовки»?).

1
ответ дан 30 November 2019 в 03:16
поделиться

Если ваши данные на самом деле являются ASCII (т.е. 7-битными данными), тогда вы должны использовать новую строку (данные, " US-ASCII ") вместо того, чтобы зависеть от кодировки платформы по умолчанию. Это может быть быстрее, чем пытаться интерпретировать его как кодировку по умолчанию для вашей платформы (это может быть UTF-8, что требует большего самоанализа).

Вы также можете ускорить это, избегая каждый раз попадания Charset-Lookup, кэшируя экземпляр Charset и вместо этого вызывая new String (data, charset) .

Сказав это: прошло очень, очень много времени с тех пор, как я видел настоящие данные ASCII в производственной среде

8
ответ дан 30 November 2019 в 03:16
поделиться
1
ответ дан 30 November 2019 в 03:16
поделиться

Необходимо отложить обработку массива байт [] до тех пор, пока log4j не решит, что он действительно хочет зарегистрировать сообщение. Таким образом, его можно зарегистрировать на уровне DEBUG, например, во время тестирования, а затем отключить во время производства. Например, вы можете:

final byte[] myArray = ...;
Logger.getLogger(MyClass.class).debug(new Object() {
    @Override public String toString() {
        return new String(myArray);
    }
});

Теперь вы не платите штраф за скорость, если вы на самом деле не регистрируете данные, потому что метод toString не вызывается, пока log4j не решит, что он действительно будет регистрировать сообщение!

Теперь я не уверен, что вы имеете в виду под «очевидным представлением», поэтому я предположил, что вы имеете в виду преобразование в последовательность, переинтерпретировав байты как кодировку символов по умолчанию. Теперь, если вы имеете дело с двоичными данными, это очевидно бесполезно. В этом случае я бы предложил использовать Arrays.toString (байт []) для создания форматированного ряда по строкам

[54, 23, 65, ...]
-121--251870-

JTS является лучшим свободным вариантом с открытым исходным кодом. Метод, который вы ищете в JTS, здесь

Что касается коммерческих вариантов, то у вас есть Java JNI версия ESRI их библиотеки ArcObjects, которая имеет очень надежную библиотеку геометрии. Интерфейс на библиотеке ESRI называют ITopologicalOperator

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

-121--2521499-

ASCII является одним из немногих кодировок, которые можно преобразовать в/из UTF16 без арифметических или табличных поисков, так что можно преобразовать вручную:

String convert(byte[] data) {
    StringBuilder sb = new StringBuilder(data.length);
    for (int i = 0; i < data.length; ++ i) {
        if (data[i] < 0) throw new IllegalArgumentException();
        sb.append((char) data[i]);
    }
    return sb.toString();
}

Но убедитесь, что это действительно - ASCII, или вы закончите с мусором.

17
ответ дан 30 November 2019 в 03:16
поделиться
Другие вопросы по тегам:

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