Jawa / Говнокод #15809 Ссылка на оригинал

0

  1. 1
short someShort = (short) (someBoolean ? 15 : 42);

такая удобная Java

Запостил: evg_ever evg_ever, (Updated )

Комментарии (118) RSS

      • скорее всего экономия памяти.
        под short надо 2 байта, а под int 4.
        Ответить
          • выравнивание стэка как правило равно размеру регистра, так как это то что на стэк записывается. поэтому все (целочисленые) переменные которые по стэку передаются, выравниваются на размер регистра. (но с другой стороны жаба не обязана поддерживать соглашения ABI.)

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

            выравнивание стэка на 16 байт это ты скорее всего путаешь с выравниванием стэк фрэйма: размер параметров функции (как и суммарный размер локальных переменных) часто выравнивается на 16/32 байт. для того что бы cache line alignment был.
            Ответить
            • В гцц видел дырку между аргументами функции int и short размером в 16 байт. Если 2 инта то дырки нет.
              Ответить
              • А если 2 шорта? Скорее всего аргументы на стеке тупо догоняются до интов.
                Ответить
                  • в контексте нужно различать два разных "на стеке": "аргументы функции на стеке" и "локальные переменные на стеке." до размера регистров догоняются только аргументы. и догоняются они только внутренне: с точки зрения программы, они все равно шорты/чары.
                    Ответить
              • странно. я много стеков ковырял, включая гцц, но больших дырок никогда не видел. короткий тест на линухе.64 дырок тоже не показал.
                Ответить
                  • FreeBSD clang 3.3 (x86_64) - 2
                    FreeBSD clang 3.3 (x86_64 -m32) - КРОВЬ КИШКИ skipping incompatible /usr/lib/libc++.so.1 when searching for /usr/lib/libc++.so.1 (я не ставил пакета совместимости с x86, увы)
                    Linux gcc 4.7.3 (x86_64) - 4
                    Linux gcc 4.7.3 (x86_64 -m32) - 20

                    Немного переписал пример, и посмотрел, что происходит в асме:
                    void shit(int a, short b) {
                      std::printf("%p %p %llu\n",
                        &a,
                        &b,
                        (unsigned long long)((uintptr_t)&a - (uintptr_t)&b)
                      );
                    }

                    sub esp, 0x3c
                    mov eax, dword ptr [esp+0x44] ; второй аргумент, ибо 0x44 - 0x3c = 8 (пропускаем адрес возврата и первый аргумент)
                    mov word ptr [esp+0x2c], ax ; кладем этот short в локальную переменную на стеке
                    lea eax, [esp+0x2c] ; адрес локальной переменной
                    lea edx, [esp+0x40] ; адрес первого аргумента на стеке
                    sub, edx, eax
                    mov dword ptr [esp+0x10], edx ; это будет тот самый последний аргумент printf, то есть разница указателей

                    Короче, для инта в качестве адреса он берет адрес параметра на стеке. Short же почему то перекладывает в локальную переменную нового фрейма, и берет уже её адрес.
                    Ответить
                    • Linux clang 3.3 (x86_64) - 2
                      Linux clang 3.3 (x86_64 -m32) - 2

                      Во втором случае он решил не рисковать, и переложил обе переменные в новый фрейм. (В первом, очевидно, тоже, ибо в amd64 аргументы через регистры передаются, так что выгружать на стек в любом случае надо явно)
                      Ответить
                  • http://ideone.com/ExQbuZ

                    ХЕЗ. какая-то оптимизация того как аргументы на стек ложатся.

                    и 32 битного ABI под рукой нет что бы посмотреть в детали.
                    Ответить
            • >но на локальные переменные это правило не распространяется. локальные переменные как правило выравнены по размеру своего типа, подобно как в структурах.
              Почему?
              Ответить
              • аргументы: где-то читал что это старая конвенция из С, и что-то там ломается если делать по другому. деталей сам не знаю. (вроде бы как для va_args это и не надо - но в ихних сырцах и находил что на стеке целые числа до int/long расшираются.)

                локальные переменные: а почему бы и нет? в ABI так написано.
                Ответить
              • > локальные переменные как правило выравнены по размеру своего типа, подобно как в структурах
                Патамушта эти ваши ARM'ы в андроидах и айфонах и прочие не x86 не любят криво выровненные данные.
                Ответить
                  • Да ну? Двухбайтовые на 2 байта, четырехбайтовые на 4 и т.п. Разве не так?
                    Ответить
                    • На 2 байта - это с точки зрения проца невыровняно.
                      Ответить
                      • Двухбайтовое на 2 байта с точки зрения проца как раз выровнено. Четырехбайтовое на 2 - нет.
                        Ответить
                  • это просто нереально!
                    http://java-performance.info/overview-of-memory-saving-techniques-java/
                    byte, boolean 1 byte
                    short, char 2 bytes
                    int, float 4 bytes
                    long, double 8 bytes
                    Byte, Boolean 16 bytes
                    Short, Character 16 bytes
                    Integer, Float 16 bytes
                    Long, Double 24 bytes


                    я кстати может чего-то не понимаю, но нахера 16 байт под булевой тип? или я хрень какую-то нашел? 🙂
                    в шарпике
                    A Boolean value occupies one byte of memory. The byte's low-order bit is used to represent its value. A value of 1 represents true; a value of 0 represents false.
                    Ответить
                    • >но нахера 16 байт под булевой тип?
                      Шура, а сколько вообще инстансов типа Boolean вам нужно для счастья?
                      Аlignment.
                      >boolean 1 byte
                      >A Boolean value occupies one byte of memory. The byte's low-order bit is used to represent its value.
                      Это пиздёж. Зависит строго от JVM и как boolean выглядит, если массив - будут биты, в классе надо доравнять до 8-байтной границы.
                      Ответить
                        • >Он о шарпе же.
                          Тоже пиздёж.
                          A bool is actually only 1 byte, but alignment may cause 4 bytes to be used on a 32-bit platform, or even 8 bytes on a 64-bit platform. For example, the Nullable<bool> (aka bool?) type uses a full 32 or 64 bits—depending on platform—even though it's comprised of just two bools. EDIT: As pointed out by Jon Skeet, padding for alignment isn't always present. As an example, an array of Nullable<bool>s takes only 2 bytes per object instead of 4 or 8.
                          http://stackoverflow.com/questions/294905/why-in-net-system-boolean-takes-4-byte

                          The caveat is that when *marshalling* Bools are defined to be 32bits, i.e. 4bytes.

                          bool b=false; Console.WriteLine(System.Runtime.Interop Services.Marshal.SizeOf(b).ToString());
                          it prints 4 byte:)
                          Ответить
                            • о мой бог, в c# для этого есть bool?, он же Nullable<bool>, который занимает 2 байта, и юзать его можно хоть у черта на рогах.
                              Ответить
                              • Если бы разрабы шарпа не пофиксили самые вопиющие проблемы жабы - их смело можно было бы считать идиотами.
                                Ответить
                              • > юзать его можно хоть у черта на рогах

                                потому что там реализация дженериков другая - reified generics.
                                Ответить
                                • конечно есть int, куда без него 🙂 точно так же, как и все остальные.
                                  вообще непонятно, почему примитивы не могут быть в коллекциях
                                  http://www.dotnetperls.com/int
                                  Ответить
                                  • > вообще непонятно, почему примитивы не могут быть в коллекциях

                                    На досуге подумай или почитай, какие подходы можно использовать для реализации дженериков, какие последствия влечёт каждая реализация и какие требования к рантайму она предоватвляет.
                                    Ответить
                                    • > int? с вопросиком.

                                      вопросик это сахар для Nullable<T> где T может быть любым примитивом.
                                      Ответить
                                      • >C# supports two kinds of variable types:
                                        >•Value types
                                        >These are the built-in primitive data types, such as char, int, and float, as well as user-defined types declared with struct.

                                        >•Reference types
                                        >Classes and other complex data types that are constructed from the primitive types. Variables of such types do not contain an instance of the type, but merely a reference to an instance.

                                        >Nullable<T>
                                        >Тип называется допускающим значение NULL, если ему может быть присвоено как непустое значение, так и значение null, означающее, что значение у типа отсутствует. По умолчанию все ссылочные типы, например String, допускающих значение NULL, но все типы значений, например Int32, нет.

                                        >В C# и Visual Basic, в случае тип значения в качестве обнуляемой нотация ? после типа значения. Например, int? в C# в объявляет тип целого числа, можно присвоить null.

                                        [SerializableAttribute]
                                        public struct Nullable<T>
                                        where T : struct

                                        короче говоря, это только для структур сделано.
                                        Ответить
                                            • > мануал для java программеров, как с c# соскочить
                                              Зачем соскакивать с решеток на жабу?!
                                              Ответить
                                          • Ну в смысле Nullable<bool> это объект Nullable со ссылкой на переменную Bool, как в жавке, или объект со свойством bool?
                                            Ответить
                                            • вот определение Nullable
                                              [Serializable, StructLayout(LayoutKind.Sequential)]
                                              public struct Nullable<t> where T : struct
                                              {
                                                  // These 2 fields represent the state
                                                  private Boolean hasValue = false; // Assume null
                                                  internal T value = default(T); // Assume all bits zero
                                                  public Nullable(T value)
                                                  {
                                                      this.value = value;
                                                      this.hasValue = true;
                                                  }
                                                  public Boolean HasValue { get { return hasValue; } }
                                                  public T Value
                                                  {
                                                      get
                                                      {
                                                          if (!hasValue)
                                                          {
                                                              throw new InvalidOperationException(
                                                              "Nullable object must have a value.");
                                                          }
                                                          return value;
                                                      }
                                                  }
                                                  public T GetValueOrDefault() { return value; }
                                                  public T GetValueOrDefault(T defaultValue)
                                                  {
                                                      if (!HasValue) return defaultValue;
                                                      return value;
                                                  }
                                                  public override Boolean Equals(Object other)
                                                  {
                                                      if (!HasValue) return (other == null);
                                                      if (other == null) return false;
                                                      return value.Equals(other);
                                                  }
                                                  public override int GetHashCode()
                                                  {
                                                      if (!HasValue) return 0;
                                                      return value.GetHashCode();
                                                  }
                                                  public override string ToString()
                                                  {
                                                      if (!HasValue) return "";
                                                      return value.ToString();
                                                  }
                                                  public static implicit operator Nullable<t>(T value)
                                                  {
                                                      return new Nullable<t>(value);
                                                  }
                                                  public static explicit operator T(Nullable<t> value)
                                                  {
                                                      return value.Value;
                                                  }
                                              }

                                              думаю ты все и сам поймешь 🙂
                                              Ответить
                                              • Так это ссылка на обертку к примитивному типу или примитивный тип в самом объекте?
                                                Ответить
                                                  • Ах, там флаг отдельно для null.

                                                    Роман, что-то знаешь, чего еще не знаю я? Молодец.

                                                    >примитивный тип в самом объекте
                                                    И это шарповые дженерики могут? Респект.
                                                    Ответить
                                                    • > Роман, что-то знаешь, чего еще не знаю я? Молодец.
                                                      да если бы, я на шарпе не пишу. Тут уже 5 раз разжевали, даже сорцы реализации привели.
                                                      Ответить
                                                • > примитивный тип в самом объекте
                                                  примитивный тип в самом объекте
                                                  Ответить
                        • > а чем bool от Boolean отличается?
                          Ничем. Короткий псевдоним, такой же как string для System.String
                          Ответить
                    • > но нахера 16 байт под булевой тип
                      Потому что Boolean это объект, блджад! Со всеми вытекающими последствиями. Об него можно даже синхронизироваться при желании.

                      Еще не забывай про 4 байта на ссылку, которая на этот Boolean будет указывать.
                      Ответить
          • выравнивание в 16 байт актуально для объектов, а не для локальных переменных. или я путаю?
            Ответить
            • Для объектов и для стековых фреймов, по идее. Для каждой переменной само собой не нужно.
              Ответить
                • Что почему?

                  Потому что переменные внутри фрейма можно разложить поплотнее, если мы знаем, что фрейм выровнен на 16 байт.
                  Ответить
                      • Много букв и ни слова о хохлах и ватниках. Ниасилит.
                        Ответить
                      • Я плохо из этого понял, когда и на какую границу надо выравнивать данные.
                        Ответить
                        • Любой вменяемый компилятор сам все сделает как надо, если ему не мешать.

                          Я ж не со зла писал "тебе - не нужно, ты же не байтоёб-сишник какой-нибудь". Оно действительно не нужно, пока не начинаешь заниматься байтоёбством 🙂
                          Ответить
                          • Я хочу понять, почему компилятор иногда делает так, а иногда этак.
                            Ответить
                          • И оно пригодится и без байтоёбства, когда захочется узнать, почему прога потребляет столько памяти.
                            Ответить
                            • Считать байты - это байтоёбство 😉

                              Да и в 99% случаев на выравниваниях ты много не выиграешь. Ссылки, системная инфа в объектах, кишки коллекций и т.п. всяко больше жрут.
                              Ответить
                                • > Кроме массивов.
                                  Ну а в массив ты сможешь пихать только примитивы и структуры (если мы о шарпе). Примитивы в массивах всегда будут лежать плотно, без выравниваний. Вот и остается только массив мелких структур, в которых ты юзаешь типы разных размеров (например byte и int), тот самый 1% 🙂

                                  P.S. Кстати, а шарп имеет право менять местами поля в структурах/классах? Если да - то он и тут все сделает за тебя, и выиграть на выравниваниях уже ничего не получится...
                                  Ответить
                                  • А массивов обьектов не бывает?

                                    >тот самый 1% 🙂
                                    Но это вполне реальный случай
                                    Ответить
                                    • > А массивов обьектов не бывает?
                                      Я не уверен, но это скорее всего будет массив из ссылок на объекты.

                                      > Но это вполне реальный случай
                                      Ну как сказать... Разве что в каких-то вычислительных задачах. Может быть еще в векторной графике.

                                      P.S. Один хрен, больше чем вдвое структура от выравнивания не растянется.
                                      Ответить
                                      • >Я не уверен, но это скорее всего будет массив из ссылок на объекты.

                                        А ну да. Но все же.

                                        Хватит меня отговаривать 🙂 Иди лучше SRP настрой.
                                        Ответить
                                      • >Один хрен, больше чем вдвое структура от выравнивания не растянется.
                                        структуры по сути памяти вообще занимают копейки.
                                        Class version
                                        Size of List: 1 object 512 KB
                                        Size of internal array: 100000 objects 3.8 MB

                                        Struct version
                                        Size of List: 1 object 24 bytes
                                        Size of internal array: 1 object 4.0 MB

                                        про структуры можно тут почитать http://www.dotnetperls.com/struct
                                        Ответить
                                  • вообще-то меняет, но это поведение вроде как можно изменить.
                                    http://msdn.microsoft.com/en-us/magazine/jj863136.aspx
                                    If _data and _initialized are ordinary (that is, non-volatile) fields, the compiler and the processor are allowed to reorder the operations so that Init executes as if it were written like this...

                                    Volatile Fields The C# programming language provides volatile fields that constrain how memory operations can be reordered. The ECMA specification states that volatile fields provide acquire-­release semantics
                                    Ответить
                        • Например, системы типа х8б используют страницы размером 4 Кб, и, если вы попытаетесь зарезервировать 18 Кб памяти, на самом деле будет зарезервировано 20 Кб.
                          как-то так.
                          Ответить
                            • что значит где?
                              class cls {
                              int a; //2 bytes
                              DateType b; //8 bytes
                              ..
                              }
                              и так далее
                              в данном случае будет 10 байт, но зарезервирует 12, так как страницы по 4 байта.
                              чет я сам запутался уже, почему до 16 выравнивать надо 🙂
                              просто надо учитывать, что чем больше объектов ты будешь создавать, тем больше зарезервированных дырок в памяти у тебя будет, и тем больше раз нужно будет запрашивать страницы из памяти
                              Ответить
                              • >чет я сам запутался уже,
                                То-то и оно. Сам разберись сначала.
                                Ответить
                              • При чем здесь размер страницы? Размер страницы на x86 - это 4 кибибайта (4096 байт), а не 4 байта.

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

                                // этим чарам выравнивание не нужно
                                // так что размер всего будет 10 
                                class A {
                                    uint16_t a;
                                    struct {
                                        char x[8];
                                    } b;
                                };
                                
                                // здесь sizeof(B) == 16
                                // потому что uint64_t нужно выравнивание 8
                                // в памяти будет 2 байта 'a', 6 байт дырка, и 8 байт 'b'
                                class B {
                                    uint16_t a;
                                    struct {
                                        uint64_t;
                                    } b;
                                };
                                Ответить
                                  • uint64_t ты не можешь туда положить, потому что ему нужно выравнивание 8.
                                    Ответить
                                    • То есть, выравнивание должно быть на размер элемента, к которому обращаются, если он влазит в регистр проца?
                                      Ответить
                                        • т.е. больше чем на битность процессора выравнивать не надо?
                                          Ответить
                                          • Отнюдь. Во всяких SSE есть такой тип, четырехкомпонентные float-векторы, и их стоит по 16 байт (128 бит) выравнивать. Причем доступ по невыровненному адресу будет не просто тормозить, а бросать процессорное исключение.
                                            Ответить
                                              • Из SSE-инструкций бросают, на самом деле, только MOVAxxx (MOVAPS, MOVAPD, etc.). MOVUxxx (MOVUPS, etc.) не бросают. "Нормальные" невекторные инструкции не бросают никогда, насколько помню.
                                                Ответить
                    • Тебе - не нужно, ты же не байтоёб-сишник какой-нибудь. Иди дальше питона души.
                      Ответить
                      • Тебе тогда вообще ничего не нужно, только консоль из срачла доставать время от времени, чтобы в туалет сходить.
                        Ответить
                        • > консоль из срачла доставать время от времени, чтобы в туалет сходить
                          Нафуя ее доставать? Вывод перенаправил в /dev/null да и все.
                          Ответить
                        • > консоль из срачла доставать
                          Почему мне кажется, что этот пациент из старых на гк под другим ником?
                          Ответить
                            • Не "может быть", а совершенно очевидно с первого поста.
                              И не с двачей, а с сосачей.
                              Ответить
                              • Потому, что консолечку в срачле стали форсить уже после того, как двачи закрылись?
                                Ответить
                          • >из старых на гк под другим ником?
                            anonimb84a2f6fd141
                            Таким?

                            И кто для пользователя с id>6000 "старые на гк":?
                            Ответить
        • я short/char индексами/этц пользуюсь изредка как нотацией что типа: не разбегайтесь, работаете с ограниченым ресурсом.
          Ответить

Добавить комментарий

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8