1

我正在尝试加快以下代码的速度,在给定字符串列表的情况下,str_list我试图将字符串转换为数字 ( unpack) 并将此数字分配到嵌套列表的正确位置data。的尺寸data大致为data[4][20][1024]. 不幸的是,这个函数运行得很慢。这是代码:

for abs_idx in range(nbr_elements):

    # get string
    this_element = str_list[abs_idx]

    # convert into number
    this_element = unpack('d', this_element)[0]

    # calculate the buffer number
    buffer_nbr = abs_idx / NBR_DATA_POINTS_PER_BUFFER_INT

    # calculate the position inside the buffer
    index_in_buffer = abs_idx % NBR_DATA_POINTS_PER_BUFFER_INT

    # write data into correct position
    data[file_idx][buffer_nbr][index_in_buffer] = this_element

我还尝试了以下替代解决方案,它甚至更慢:

# convert each string into a number
unpacked_values = [unpack('d', str_list[j])[0] for j in range(nbr_elements)]
for abs_idx in range(nbr_elements):

    # calculate the buffer number
    buffer_nbr = abs_idx / NBR_DATA_POINTS_PER_BUFFER_INT

    # calculate the position inside the buffer
    index_in_buffer = abs_idx % NBR_DATA_POINTS_PER_BUFFER_INT

    # write data into correct position
    data[file_idx][buffer_nbr][index_in_buffer] = unpacked_values[abs_idx]

令我惊讶的是,下一个实现是最慢的(我预计它是最快的):

# convert each string into a number
unpacked_values = [unpack('d', str_list[j])[0] for j in range(nbr_elements)]

# calculate all buffer numbers at once
buffer_ids = np.arange(nbr_elements) / NBR_DATA_POINTS_PER_BUFFER_INT

# calculate all positions inside the buffer at once
index_in_buffer_id = np.arange(nbr_elements) % NBR_DATA_POINTS_PER_BUFFER_INT

for abs_idx in range(nbr_elements):
    data[file_idx][buffer_ids[abs_idx]][index_in_buffer_id[abs_idx]] = unpacked_values[abs_idx]

为什么连续的实现表现更差?个人瓶颈在哪里?我怎样才能加快我的初始代码?

编辑:从我的分析测试中,以下两个步骤是瓶颈:运行unpack并将值分配给data. 我不知道如何加快这些步骤。

EDIT2:我需要使用unpack,因为我的字符串是十六进制的。

EDIT3: values = unpack("d" * n, "".join(str_list))解决了解包速度慢的问题。尽管如此,使用三重(原始)或双重(修改)嵌套循环对数据的分配占用了 50% 的时间。有没有办法减少这个时间?

4

3 回答 3

1

一些优化:

  1. 一次拆开所有的刺
  2. 循环前获取项目数据[file_idx]

尝试一下:

n = len(str_list)
values = unpack("d" * n, "".join(str_list))

a = data[file_idx]

# Just to shorten this code sample
q = NBR_DATA_POINTS_PER_BUFFER_INT

for i in xrange(n):
    a[i / q][i % q] = values[i]

顺便说一句,您是否分析了代码的哪一部分花费的时间最多?

更新:

n = len(str_list)
values = unpack("d" * n, "".join(str_list))

# Just to shorten this code sample
q = NBR_DATA_POINTS_PER_BUFFER_INT

data[file_idx] = [values[i:i+q] for i in xrange(0, n, q)]
于 2012-05-24T18:08:57.310 回答
1

这是不是更快?它减少了一些查找并且不需要使用所有字符串的数字制作中间列表?

df = data[file_idx]
index = 0
for value in str_list:
    # not sure what unpack does... is there a faster function 
    # that does the same?
    number = unpack('d', value)[0]

    # calculate the buffer number
    buffer_nbr = index / NBR_DATA_POINTS_PER_BUFFER_INT

    # calculate the position inside the buffer
    index_in_buffer = index % NBR_DATA_POINTS_PER_BUFFER_INT

    # write data into correct position
    df[buffer_nbr][index_in_buffer] = number

    index += 1
于 2012-05-24T18:27:05.240 回答
0

这个怎么样:

df = data[file_idx]
index = 0
bufnr = 0
buf = df[0]
for value in str_list:
    # not sure what unpack does... is there a faster function 
    # that does the same?
    number = unpack('d', value)[0]

    buf[index] = number

    index += 1

    if index >= NBR_DATA_POINTS_PER_BUFFER_INT:
        index = 0
        bufnr += 1
        buf = df[bufnr]

难道数据是字典而不是列表?

于 2012-05-24T19:32:45.743 回答