1. Python / Говнокод #18917

    −11

    1. 1
    array.array(itertools.repeat(0, 1024*1024*1024))

    Toooo sloooow...

    Неужели в питоне нету быстрого способа набить в array пачку ноликов?

    Запостил: bormand, 26 Октября 2015

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

    • SEO comment
      Ответить
    • Вот такое говнецо пришло в голову:
      def make_byte_array(size):
          if size == 0:
              return array.array('B', [])
          a = make_byte_array(size // 2)
          a.extend(a)
          if size % 2:
              a.append(0)
          return a
      Работает на порядки быстрее решения из топика ;)

      2.2 секунды на 4 гига.
      Ответить
      • на перле на эти же грабли в прошлом наступал (делал стресс-тест для памяти) - и решение было подобным. (я просто в лоб с оператором повторения из 1КБ делал 1МБ, и из него делал 1ГБ - работало на порядок быстрее чем `'x' x (1024*1024*1024)`).

        сейчас под рукой системы нету на новых версиях выделение 4ГБ протестировать.
        если кто хочет: time perl -e '$a="a"x(4*1024*1024*1024)'
        Ответить
    • Не в питоне а в numpy.
      в цикле extend( [0] * 1024 * 1024)
      Ответить
      • > а в numpy
        В шапке я юзал штатный питоний array, не numpy.
        Ответить
      • Такой экстенд тоже дико медленный... Разве что закешированный array на метр конкатенировать, а не список.
        Ответить
      • Вот как-то так, походу, надо:
        mem = array.array('B', [0]) * size
        Тоже за 2.2 секунды 4 гига забивает.
        Ответить
        • >> array.array

          вояяяж вояж на нара на на
          Ответить
        • Как насчет стильных, модных, молодёжных генераторов?
          devzero = [ 0 for x in xrange(0, 1 << 20) ]


          Кстати да: а в питоне можно писать в файл значения из генератора (yield)?
          Ответить
          • Ты не понял. Любая работа с высокоуровневой поеботой будет медленной. mem = array.array('B', [0]) * size же равносильно mem = array.array('B', [0]).__mul__(size), дергается метод array. И чем то что ты написал отличается от [0] * 1 << 20?

            >Кстати да: а в питоне можно писать в файл значения из генератора (yield)?
            В цикле for
            Ответить
            • > И чем то что ты написал отличается от [0] * 1 << 20?
              Мне вообще про Python известно только то, что знакомый расказывал (ну тот, что с парашютом прыгал)

              >> Кстати да: а в питоне можно писать в файл значения из генератора (yield)?
              > В цикле for
              Я тут подумал: херню сморозил.
              Ответить
        • Вполне ожидаемо на самом деле. Конструктор array принимает любой итератор, что делает неизбежными парсинг, валидацию нового элемента и реаллок содержимого самого массива на каждый элемент. array.repeat() и array.extend() реализованы уже с учетом того, что аргументом будет другой массив с элементами уже известного типа.
          Так что и тут за универсальность интерфейса пришлось заплатить пирфомансом.
          Ответить
          • > реаллок содержимого самого массива на каждый элемент
            Ну вот это не факт. Там, скорее всего, capacity и size отдельные и реаллочит он всё-таки реже.
            Ответить
            • При наличии нормального аллокатора не надо отдельно хранить капасити и сайз.
              Ответить
              • Ну суть же не меняется, просто capacity спрашиваешь у аллокатора, а не хранишь сам.
                Ответить
          • >реаллок содержимого самого массива на каждый элемент.
            Ну может там как в жавке в списке - экспоненциальное выделение памяти.
            Ответить
    • gcc -o zeros zeros.c
      os.system( 'zeros' )
      Ответить
      • Так мне их не вывести надо было :) Если бы мне просто файл с ноликами нужен был бы - я бы тупо dd'шнул их из /dev/zero.
        Ответить
    • 1ГБ ноликов?
      А питон не сдохнет от такого?
      Ответить
    • python -c 'print "array=", [0] * (1 << 20)' > zeros.py
      python
      >>> import zeros
      >>> zeros.array[0:5]
      [0, 0, 0, 0, 0]
      Ответить
      • А 1<<30 слабо?
        Ответить
        • Как сообщает газета "Байт", сегодня, 27 октября, основной сервер Яндекса дал сбой. От Одноклассников и Вконтактика были отрезаны сотни миллионов российских пользователей, пренебрегающих адресной строкой. По словам очевидцев, в полночь остановился поиск, через десять минут отказал хостинг, а ещё через пару минут все сервисы Яндекса перестали отвечать. Ведётся независимое расследование.
          Утром нам позвонил анонимный немецкий господин и сообщил "Яндекс. Кашицын. 1<<35 нулей хватит всем. Русня, ищите кампютеры, я нашёл". Таинственное сообщение расшифровать не удалось. На всякий случай мы рекомендуем не прислоняться к дверям и носить с собой зонтик.
          Ответить
    • https://pypi.python.org/pypi/cymem
      Ответить

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