此处将为大家介绍关于在'if'子句中使用'in'时的元组或列表?的详细内容,并且为您解答有关ifin语句的相关问题,此外,我们还将为您介绍关于c#–为什么在这个例子中使用比元组更快的元组?、c#–在列
此处将为大家介绍关于在'if'子句中使用'in'时的元组或列表?的详细内容,并且为您解答有关if in语句的相关问题,此外,我们还将为您介绍关于c# – 为什么在这个例子中使用比元组更快的元组?、c# – 在列表中搜索数组或列表、Java 中的数组或列表。哪个更快?、Java 中的数组或列表哪个更快?的有用信息。
本文目录一览:- 在'if'子句中使用'in'时的元组或列表?(if in语句)
- c# – 为什么在这个例子中使用比元组更快的元组?
- c# – 在列表中搜索数组或列表
- Java 中的数组或列表。哪个更快?
- Java 中的数组或列表哪个更快?
在'if'子句中使用'in'时的元组或列表?(if in语句)
哪种方法更好?使用元组,例如:
if number in (1, 2):
或清单,例如:
if number in [1, 2]:
建议将哪一种用于此类用途,以及为什么使用(出于逻辑和性能考虑)?
答案1
小编典典CPython解释器 将第二种形式替换为第一种形式 。
这是因为从常量加载元组是一个操作,但是列表将是3个操作;加载两个整数内容并构建一个新的列表对象。
由于您使用的是无法到达的列表文字,因此它将替换为元组:
>>> import dis>>> dis.dis(compile(''number in [1, 2]'', ''<stdin>'', ''eval'')) 1 0 LOAD_NAME 0 (number) 3 LOAD_CONST 2 ((1, 2)) 6 COMPARE_OP 6 (in) 9 RETURN_VALUE
这里第二字节码负载一个(1, 2)
元组为常数,在 一个 步骤。将其与创建成员资格测试中未使用的列表对象进行比较:
>>> dis.dis(compile(''[1, 2]'', ''<stdin>'', ''eval'')) 1 0 LOAD_CONST 0 (1) 3 LOAD_CONST 1 (2) 6 BUILD_LIST 2 9 RETURN_VALUE
对于长度为N的列表对象,需要N + 1个步骤。
这种替换是CPython特有的窥孔优化。见Python/peephole.c
资料来源。然后,对于
其他 Python实现,您要坚持使用不可变的对象。
也就是说,在使用Python 3.2及更高版本时, 最好的 选择是使用 set文字 :
if number in {1, 2}:
因为窥视孔优化器将用frozenset()
对象代替它,并且针对集合的成员资格测试是O(1)常数操作:
>>> dis.dis(compile(''number in {1, 2}'', ''<stdin>'', ''eval'')) 1 0 LOAD_NAME 0 (number) 3 LOAD_CONST 2 (frozenset({1, 2})) 6 COMPARE_OP 6 (in) 9 RETURN_VALUE
此优化是在Python
3.2中添加的,但并未反向移植到Python
2。
因此,Python 2优化器无法识别此选项,并且几乎可以肯定构建aset
或frozenset
从内容构建的成本比使用元组进行测试的成本更高。
集合成员资格测试是O(1)且快速;对元组进行测试是O(n)最坏的情况。尽管针对集合进行测试必须计算哈希(较高的不变成本,为不可变类型缓存),但是针对
除第一个元素之外的 元组进行测试的成本始终会更高。因此,平均而言,集合可以轻松地更快:
>>> import timeit>>> timeit.timeit(''1 in (1, 3, 5)'', number=10**7) # best-case for tuples0.21154764899984002>>> timeit.timeit(''8 in (1, 3, 5)'', number=10**7) # worst-case for tuples0.5670104179880582>>> timeit.timeit(''1 in {1, 3, 5}'', number=10**7) # average-case for sets0.2663505630043801>>> timeit.timeit(''8 in {1, 3, 5}'', number=10**7) # worst-case for sets0.25939063701662235
c# – 为什么在这个例子中使用比元组更快的元组?
这是代码:
class test { public test() { _mylistofList = new List<List<double>>(1000000); } public void Run() { for (int i = 0; i < _mylistofList.Capacity; i++) { _mylistofList.Add( new List<double>(3) { i,10*i,100*i} ); //Populate the list with data } } private List<List<double>> _mylistofList; }
我将此代码的执行速度与以下内容进行了比较:(用元组替换double的列表)
class test { public test() { _mylistofTuple = new List<Tuple<double,double,double>>(1000000); } public void Run() { for (int i = 0; i < _mylistofTuple.Capacity; i++) { _mylistofTuple.Add( new Tuple<double,double>(i,10 * i,100 * i) ); //Populate the list with data } } private List<Tuple<double,double>> _mylistofTuple; }
事实证明,使用元组似乎要快得多.我为不同的List大小运行了这段代码(从200,000个元素 – 列表中的> 5百万个元素),这是我得到的结果:
我无法真正理解这一点.为什么我会有如此显着的差异?使用存储相同类型对象的元组(这里加倍)并没有多大意义.我宁愿使用List /数组来做到这一点:我做错了什么?是否有一种方法可以使案例#1以比案例#2更快/更快的速度运行?
谢谢!
解决方法
第一个是超级简单 – 只有3个任务:
public Tuple(T1 item1,T2 item2,T3 item3) { m_Item1 = item1; m_Item2 = item2; m_Item3 = item3; }
第二个实际上是由编译器转换为3个Add方法调用:
var temp = new List<double>(3); temp.Add(i); temp.Add(10 * i); temp.Add(100 * i);
添加不仅仅是一项任务:
public void Add(T item) { if (_size == _items.Length) EnsureCapacity(_size + 1); _items[_size++] = item; _version++; }
运行更多代码,执行速度更慢.非常简单..
c# – 在列表中搜索数组或列表
List<byte> lbyte
有
byte[] searchBytes
如何搜索lbyte不仅仅是一个字节,而是搜索searchBytes的索引?
例如.
Int32 index = lbyte.FirstIndexOf(searchBytes);
这是我提出的蛮力.
不是我要找的表现.
public static Int32 ListIndexOfArray(List<byte> lb,byte[] sbs) { if (sbs == null) return -1; if (sbs.Length == 0) return -1; if (sbs.Length > 8) return -1; if (sbs.Length == 1) return lb.FirstOrDefault(x => x == sbs[0]); Int32 sbsLen = sbs.Length; Int32 sbsCurMatch = 0; for (int i = 0; i < lb.Count; i++) { if (lb[i] == sbs[sbsCurMatch]) { sbsCurMatch++; if (sbsCurMatch == sbsLen) { //int index = lb.Findindex(e => sbs.All(f => f.Equals(e))); // fails to find a match IndexOfArray = i - sbsLen + 1; return; } } else { sbsCurMatch = 0; } } return -1; }
解决方法
static int SimpleBoyerMooreSearch(byte[] haystack,byte[] needle) { int[] lookup = new int[256]; for (int i = 0; i < lookup.Length; i++) { lookup[i] = needle.Length; } for (int i = 0; i < needle.Length; i++) { lookup[needle[i]] = needle.Length - i - 1; } int index = needle.Length - 1; var lastByte = needle.Last(); while (index < haystack.Length) { var checkByte = haystack[index]; if (haystack[index] == lastByte) { bool found = true; for (int j = needle.Length - 2; j >= 0; j--) { if (haystack[index - needle.Length + j + 1] != needle[j]) { found = false; break; } } if (found) return index - needle.Length + 1; else index++; } else { index += lookup[checkByte]; } } return -1; }
然后你可以这样搜索.如果lbyte在一段时间后保持不变,你可以将它转换为一个数组并传递它.
//index is returned,or -1 if 'searchBytes' is not found int startIndex = SimpleBoyerMooreSearch(lbyte.ToArray(),searchBytes);
根据评论更新.这是IList实现,这意味着可以传递数组和列表(以及实现IList的任何其他内容)
static int SimpleBoyerMooreSearch(IList<byte> haystack,IList<byte> needle) { int[] lookup = new int[256]; for (int i = 0; i < lookup.Length; i++) { lookup[i] = needle.Count; } for (int i = 0; i < needle.Count; i++) { lookup[needle[i]] = needle.Count - i - 1; } int index = needle.Count - 1; var lastByte = needle[index]; while (index < haystack.Count) { var checkByte = haystack[index]; if (haystack[index] == lastByte) { bool found = true; for (int j = needle.Count - 2; j >= 0; j--) { if (haystack[index - needle.Count + j + 1] != needle[j]) { found = false; break; } } if (found) return index - needle.Count + 1; else index++; } else { index += lookup[checkByte]; } } return -1; }
由于数组和列表实现了IList,因此在您的情况下调用它时不需要进行转换.
int startIndex = SimpleBoyerMooreSearch(lbyte,searchBytes);
Java 中的数组或列表。哪个更快?
我必须在内存中保留数千个字符串,以便在 Java 中连续访问。我应该将它们存储在数组中还是应该使用某种 List ?
由于数组将所有数据保存在连续的内存块中(与列表不同),使用数组存储数千个字符串会导致问题吗?
Java 中的数组或列表哪个更快?
我必须在内存中保留数千个字符串,以便在 Java 中连续访问。我应该将它们存储在数组中还是应该使用某种 List ?
由于数组将所有数据保存在连续的内存块中(与列表不同),使用数组存储数千个字符串会导致问题吗?
今天关于在'if'子句中使用'in'时的元组或列表?和if in语句的分享就到这里,希望大家有所收获,若想了解更多关于c# – 为什么在这个例子中使用比元组更快的元组?、c# – 在列表中搜索数组或列表、Java 中的数组或列表。哪个更快?、Java 中的数组或列表哪个更快?等相关知识,可以在本站进行查询。
本文标签: