Memset на векторном C++

Это может быть более быстро, чем Ваш. Не делает предположений о длине строки. Спины через файл один блок за один раз, пока это не нашло правильное количество '\n' символами.

def tail( f, lines=20 ):
    total_lines_wanted = lines

    BLOCK_SIZE = 1024
    f.seek(0, 2)
    block_end_byte = f.tell()
    lines_to_go = total_lines_wanted
    block_number = -1
    blocks = [] # blocks of size BLOCK_SIZE, in reverse order starting
                # from the end of the file
    while lines_to_go > 0 and block_end_byte > 0:
        if (block_end_byte - BLOCK_SIZE > 0):
            # read the last block we haven't yet read
            f.seek(block_number*BLOCK_SIZE, 2)
            blocks.append(f.read(BLOCK_SIZE))
        else:
            # file too small, start from begining
            f.seek(0,0)
            # only read what was not read
            blocks.append(f.read(block_end_byte))
        lines_found = blocks[-1].count('\n')
        lines_to_go -= lines_found
        block_end_byte -= BLOCK_SIZE
        block_number -= 1
    all_read_text = ''.join(reversed(blocks))
    return '\n'.join(all_read_text.splitlines()[-total_lines_wanted:])

мне не нравятся хитрые предположения о длине строки, когда - на практике - Вы никогда не можете знать подобные вещи.

Обычно это определит местоположение последних 20 строк на первой или второй передаче через цикл. Если Ваши 74 символьных вещи на самом деле точны, Вы делаете размер блока 2048, и Вы выследите 20 строк почти сразу.

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

44
задан Kevin Panko 27 June 2011 в 20:17
поделиться

3 ответа

Используйте std :: fill () :

std::fill(myVector.begin(), myVector.end(), 0);
81
ответ дан 26 November 2019 в 21:51
поделиться

Если ваш вектор содержит типов POD , можно безопасно использовать для него memset - хранение вектора гарантированно будет непрерывным.

memset(&vec[0], 0, sizeof(vec[0]) * vec.size());

Изменить: Извините, что бросил вам неопределенный термин - POD означает Обычные старые данные , то есть типы, которые были доступны в C, и структуры, построенные из них.

Изменить еще раз: Как указано в комментариях, хотя bool - простой тип данных, vector представляет собой интересное исключение и потерпит неудачу, если вы попытаетесь использовать для него memset. Ответ Адама Розенфилда по-прежнему отлично работает в этом случае.

25
ответ дан 26 November 2019 в 21:51
поделиться

Другой способ, думаю, я впервые увидел это в книге Мейерса:

// Swaps with a temporary.
vec.swap( std::vector<int>(vec.size(), 0) );

Единственный недостаток этого метода в том, что он делает копию.

2
ответ дан 26 November 2019 в 21:51
поделиться
Другие вопросы по тегам:

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