- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
当整个字符串的长度事先已知时,我试图通过连接多个较短的字符串来找出创建长字节字符串(或 bytearray)的最有效方法。我制作了这个脚本并得出了这些结果:
import time
MSG = b'test message'
COUNT = 30000
def bytes_list_test():
tStart = time.clock()
l = []
for i in range(COUNT):
l.append(MSG)
bs = b''.join(l)
print('byte list time:', time.clock() - tStart)
def bytearray_test():
tStart = time.clock()
ba = bytearray()
for i in range(COUNT):
for c in MSG:
ba.append(c)
print('array time:', time.clock() - tStart)
def initialized_bytearray_test():
tStart = time.clock()
ba = bytearray([0x00]*len(MSG)*COUNT)
for i in range(COUNT):
ba[i*len(MSG):i*len(MSG)+len(MSG)] = MSG
print('initialized array time:', time.clock() - tStart)
bytes_list_test()
bytearray_test()
initialized_bytearray_test()
结果:
byte list time: 0.0076534920117410365
array time: 0.08107178658246994
initialized array time: 0.08843219671325642
几个问题:
1) 创建字节列表并使用 join() 方法是结果所暗示的方式吗?
2) 为什么使用字节列表比使用似乎专为此类事物设计的字节数组快得多?
3) 你会认为初始化数组会比未初始化数组更快,因为初始化数组不必调整大小(请注意,它偶尔会表现得更好,但幅度不大且不一致)。不是因为切片操作更快吗?
最佳答案
第一个函数创建指向同一对象的指针列表(不是字节列表),然后 join
将执行一次内存分配和 COUNT
调用 memcpy
.
您可以通过删除临时列表并使用 itertools.repeat
来加快第一个函数的速度(在我的测试中是 5 倍):
def bytes_list_test_opt():
tStart = time.clock()
bs = b''.join(itertools.repeat(MSG, COUNT))
print('byte list opt time:', time.clock() - tStart)
或者,在这种特殊情况下,只需使用 bytes
对象的 *
运算符,它就是这样做的:
bs = MSG*COUNT
第二个函数重复遍历 MSG
,逐字节存储数据,并且随着字节数组的增长必须重复重新分配内存。
通过将迭代替换为对 extend
的单个调用,您可以使第二个函数几乎与原始(未优化的)第一个函数一样快:
def bytearray_test_opt():
tStart = time.clock()
ba = bytearray()
for i in range(COUNT):
ba.extend(MSG)
print('array opt time:', time.clock() - tStart)
此修改后,第二个函数将比第一个函数慢,这仅仅是因为额外的重新分配(在我的测试中约为 15%)。
第三个函数使用 bytearray
的切片赋值,它接受可迭代的并且似乎在进行相同的逐字节迭代,但没有意识到它们可以只是 memcpy
字节到位。这看起来像是标准库中可以修复的缺陷。
正如您从之前的优化中看到的,与逐字节复制相比,分配所花费的时间非常少,因此预分配在这里没有明显的影响。您可以通过减少计算来节省一些时间,但这也无济于事:
def initialized_bytearray_test_opt():
tStart = time.clock()
L = len(MSG)
ba = bytearray(L*COUNT)
ofs = 0
for i in range(COUNT):
ba[ofs : ofs+L] = MSG
ofs += L
print('initialized array opt time:', time.clock() - tStart)
我机器的最终计时:
byte list time: 0.004823000000000001
byte list opt time: 0.0008649999999999977
array time: 0.043324
array opt time: 0.005505999999999997
initialized array time: 0.05936899999999999
initialized array opt time: 0.040164000000000005
附言使用 timeit
模块来执行这样的测量,它提供了更高的准确性。
关于Python bytearray 与字节列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17162609/
如标题所示,ans_list是一个答案列表,ans_index是一个数字(答案在词汇表中的索引,但与atm无关) 这里生成的 tree.anslist 是什么? (例如,仅针对第一个),忽略迭代。 f
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将具有一个元素的东西拿走。 这与 How do I “flatte
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将带有一个元素的东西拿走。 这与 How do I “flatte
这个问题已经有答案了: Convert nested list to 2d array (3 个回答) 已关闭 7 年前。 java中有没有快捷方式可以转换 List> 到 String[][] ?
我在排序时遇到问题 List> 。我创建了一个自定义比较器,在其中编写了对数据进行排序的代码。 public class CustomComparator implements Comparator
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Java Generics: Cannot cast List to List? 我只是想知道为什么下面的java代
试图想出一个 LINQy 方法来做到这一点,但我什么也没想到。 我有一个对象列表<>,其中包含一个属性,该属性是逗号分隔的字母代码列表: lst[0].codes = "AA,BB,DD" lst[1
假设我有这些任务: points = [] point = (1, 2) 我怎么会这样做: points += point 它工作得很好,并且给了我点 = [1, 2]。但是,如果我这样做: poin
如何在 scala 中将 List[Task[List[Header]]] 类型转换为 Task[List[Header]]。 我有一个方法返回 Task[List[Header]] 并多次调用 do
如何在 Java 中查找二维列表的元素? 我有一个参数为 List> 的函数我想知道如何找到这个列表的行和列。 最佳答案 如果你喜欢 List> obj 然后你就可以像这样访问 obj.get(cur
分配 List到 List工作正常。 分配 List>到 List>不编译。 代码 public class Main { public static void main(String[] a
我正在用 Java 编写一个方法,该方法必须接收并迭代 Serializable 的 List。 有什么区别: public void myMethod(List list) { } 和 public
我看到很多人想用 mvvm 更新网格/列表/树的一部分,但他们不想刷新整个列表。 对于所有遇到此问题的人,我做了以下示例。 希望这对你有用。 最佳答案 这是一个简单的例子。整个代码中最重要的是: Bi
我正在为现有的 C++ 库编写包装器,该库使用列表,其中 T 是自定义结构。我被建议使用 vector 而不是列表,但我试图避免修改库。 为了更好地理解这个场景,我做了一个简单的应用程序,使用一个列表
List list List list 这两种声明有什么区别吗? 谢谢, 最佳答案 是的。 List可以包含所有派生自 Base 的不同事物的混合物. List包含同质项(从某种意义上说,它们必须全部
有人可以尽可能详细地解释以下类型之间的区别吗? List List List 让我更具体一点。我什么时候想使用 // 1 public void CanYouGiveMeAnAnswer(List l
我有一个元组列表,每个元组都是一对列表。所以我的数据看起来像: mylist = [(['foo', 'bar'], ['bar', 'bar']),(['bar', 'bar'],['bar', '
也许是一个时髦的标题,但我遇到了以下问题: 给定一个类型为 (a * b) list 的列表,我想创建一个类型为 (a * b list) list 的新列表。一个例子: 给定列表 let testL
我是一名优秀的程序员,十分优秀!