我一定是忽略了某些东西,但真的看不出为什么Python代码会这么慢......
在一个元素范围为[−1,000,000..1,000,000]的数组中计算唯一元素,并使用位向量来完成。使用BitSet
的Java代码大约比Python快50倍,Python需要9秒钟。
这可能是因为当我初始化 bitvector = 0
时,Python没有预留足够的内存,随着位向量的增长,它需要被复制吗?
Python:
def solution(array):
bitvector = 0
count = 0
for element in array:
# transform -1,000,000 to 0 etc
element_transformed = element + 1000000
if bitvector >> element_transformed & 1 == 0:
count += 1
bitvector = bitvector | 1 << element_transformed
return count
测试:
import unittest
import random
from .file1 import solution
class MySolutionTests(unittest.TestCase):
def test_solution_random_all_unique(self):
a = random.sample(range(-1000000, 1000001), 100000)
self.assertEqual(100000, solution(a))
在Java中:
package mypackage;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
public class MyClass {
public static int solution(List<Integer> array) {
BitSet bitvector = new BitSet();
int count = 0;
for(int i = 0; i < array.size(); i++) {
int elementTransformed = array.get(i) + 1000000;
if(bitvector.get(elementTransformed) != true) {
count++;
bitvector.set(elementTransformed, true);
}
}
return count;
}
public static void main(String[] args) {
// TODO code application logic here
}
}
测试:
package mypackage;
import java.util.ArrayList;
import java.util.Collections;
import org.junit.Test;
import static org.junit.Assert.*;
public class MyClassTest {
public MyClassTest() {
}
@Test
public void testSolutionLong_RandomAllUnique() {
ArrayList array = new ArrayList();
for(int i = -1000000; i < 1000000; i++) {
array.add(i);
}
Collections.shuffle(array);
assertEquals(100000, MyClass.solution(array.subList(0, 100000)));
}
}
bitvector
可以有多大?它不仅仅是一个简单的位向量,而是一个完整的任意精度整数,因此它不像简单的向量那样高效。而且 CPython 的算术运算速度并不快,特别是当数字大于机器整数时。如果你真的需要速度,那么还有其他各种选项,例如使用某种字节数组。 - PM 2Ringrandom.sample
?为什么不用shuffle
? - Daniel Roseman