Действительно ли необходимо умножиться sizeof (символ) при управлении памятью?

Посмотрите на декомпилированный класс, и вы увидите все :) Ответ должен быть следующим:

  • две строки ("xyz" и "abc") являются только ссылками на позиции в постоянном пуле поэтому они не создаются вашим кодом
  • одна строка создается напрямую (new String("xyz"))
  • конкатенация строк оптимизируется компилятором и изменяется на StringBuilder, поэтому создается последняя строка косвенно

    public java.lang.String method();
    descriptor: ()Ljava/lang/String;
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=3, args_size=1
     0: new           #2                  // class java/lang/String
     3: dup
     4: ldc           #3                  // String xyz
     6: invokespecial #4                  // Method java/lang/String."<init>":(Ljava/lang/String;)V
     9: astore_1
    10: ldc           #5                  // String abc
    12: astore_2
    13: new           #6                  // class java/lang/StringBuilder
    16: dup
    17: invokespecial #7                  // Method java/lang/StringBuilder."<init>":()V
    20: aload_1
    21: invokevirtual #8                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    24: aload_2
    25: invokevirtual #8                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    28: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
    31: astore_1
    32: aload_1
    33: areturn
    
15
задан sharptooth 18 June 2009 в 10:31
поделиться

8 ответов

Хотя в этом нет необходимости, я считаю хорошей практикой оставить sizeof (char), потому что это делает код более читаемым и позволяет избежать использования магического числа. Кроме того, если код необходимо изменить позже, чтобы вместо символа он преобразовывал размер чего-либо в указатель для этого объекта, легче изменить код, чем если бы у вас была только «1».

6
ответ дан 30 November 2019 в 23:56
поделиться

sizeof (char) всегда равно 1, независимо от того, какие операции с памятью вы выполняете.

Однако sizeof (TCHAR) может варьироваться в зависимости от вашего параметры компилятора.

14
ответ дан 30 November 2019 в 23:56
поделиться

По определению sizeof (char) всегда равен 1. Один байт - это размер символа в C, независимо от количества битов в байте (8 на обычном настольном ЦП)

Типичный пример, когда один байт не равен 8 битам, - это PDP-10 и другие старые, похожие на мини-компьютеры архитектуры с 9/36 битами байтов. Но байты, отличные от 2 ^ N, становятся чрезвычайно редкими, я считаю

Кроме того, я думаю, что это лучший стиль:

char* buf1;
double* buf2;

buf1 = malloc(sizeof(*buf1) * N);
buf2 = malloc(sizeof(*buf2) * N);

, потому что он работает независимо от типа указателя.

28
ответ дан 30 November 2019 в 23:56
поделиться

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

Конечно, это не (цитируя Википедию) «неэффективно», но я считаю это » далеко не оптимально ». Это ничего не стоит во время выполнения, но загромождает код ненужным мусором, все время сигнализируя о том, что кто-то считает это необходимым.

Также обратите внимание, что выражение не анализируется как вызов функции: sizeof не является функцией. Вы не вызываете функцию, передавая ей магический символ char . Вы применяете к выражению встроенный унарный префиксный оператор sizeof , и ваше выражение в этом случае является приведением к типу char , который в C записывается как (char) .

It '

11
ответ дан 30 November 2019 в 23:56
поделиться

Использование sizeof (char) делает ваш код более читаемым и переносимым.

В x86 мы все знаем, что символ составляет 1 байт. Но явное написание этого помогает прояснить ваши намерения, что всегда хорошо.

Кроме того, что, если ваш код будет помещен на какую-то другую платформу, где символ не 1 байт. Что, если бы вместо символа было всего 4 бита?

Согласен, в этом нет необходимости, но это не замедляет время выполнения и окупится в том редком случае, когда вам нужно перенести код на другую архитектуру.

-4
ответ дан 30 November 2019 в 23:56
поделиться

В этом нет необходимости. См. здесь (например).

sizeof (char) определяется стандартом C как всегда 1 (байт). Обратите внимание, что поскольку sizeof возвращает количество байтов , количество бит на байт не имеет значения (и на практике в любом случае равно 8).

6
ответ дан 30 November 2019 в 23:56
поделиться

Еще нужно иметь в виду, что компилятор статически знает, что значение sizeof (char) равно 1, и он также знает, что умножение числа на статическое 1 означает, что умножение не требуется; компилятор оптимизирует это. Проблемы производительности не должны рассматриваться на этих основаниях.

3
ответ дан 30 November 2019 в 23:56
поделиться

Что-то из этого зависит от того, куда вы собираетесь пойти с вашей работой: вы сегодня работаете в одиночку, но планируете ли вы (или, по крайней мере, надеетесь) построить что-то достаточно большое, что вам понадобится помощь? Если это так, то хорошо получить какие-то практики на месте заранее - не столько, что это замедлит вас, сколько то, на чем вы можете отталкиваться при создании своей команды.

Мой коллега, который оставил архитекторов больших объемов торговых систем для создания программного обеспечения для iPod и iPad, сделал некоторые мысли об этом сейчас, когда он команда из 1. Может оказаться полезным:

текст ссылки

-121--4648428-

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

Изменить: Хорошо, видимо, некоторые разъяснения в порядке. ОП специально упомянула GAE, над которой ни один из этих методов не будет работать, но я упомяну их, поскольку некоторые, кажется, делают исключение из их отсутствия.

API компилятора Java (Java 6 +) позволяет компилировать классы Java во время выполнения. Технически можно записать исходный файл Java, чтобы точно посмотреть, как вы хотите, скомпилировать и загрузить его.

Библиотеки байт-кодов Java могут перезаписывать классы во время выполнения. Это используется такими библиотеками, как JPA (и другими). Таким образом можно изменить классы.

Однако OP ссылается на a) в отношении работы с GAE и b) более в порядке того, как Javascript позволяет изменять классы или конкретные экземпляры во время выполнения, динамически добавляя, удаляя или изменяя свойства. Java, конечно, не делает этого и, в частности, не на GAE.

Вышесказанное не является исключением из этого, так же как приведение класса к char * в C++, так что вы можете читать частные члены не означает, что C++ не имеет частных членов. По сути, вы обходите среду выполнения Java с обоими этими методами, даже если они являются частью Java.

-121--2831525-

От "Новый стандарт C. экономический и культурный комментарий. "

  1. Статистика: 2,0% размера взяты из char и 1,5% - из неподписанного char . Страница 1033 в 1.2 версии книги.
  2. стр. 1037.

Количество битов в представлении символьного типа: не имеет значения. По определению номер байтов в байте, тип символа один.

Иногда разработчики инструкций по кодированию связать байт как всегда содержащий восемь битов. На хостах, где тип символа 16 бит, это может привести к неправильному предположению, что применение размера к типу символа возвращает значение 2. Эти вопросы обсуждаются в других местах.

3
ответ дан 30 November 2019 в 23:56
поделиться
Другие вопросы по тегам:

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