java - Python按位移位真的很慢吗?
问题描述
我一定是忽略了一些东西,但真的不明白为什么 Python 代码这么慢......
计算数组中元素在 [−1,000,000..1,000,000] 范围内的唯一元素,并使用位向量来执行此操作。使用的 Java 代码BitSet
比 Python 快约 50 倍,后者需要 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)));
}
}
解决方案
只是想直接回答你提出的问题。要回答为什么 Python 需要 9 秒而 Java 快 50 倍,这不是一个简单的问题。在这里,您可以很好地了解先前的讨论Python 是否比 Java/C# 慢?
我喜欢看它的方式是,Java 是一种面向对象的语言,而 python 是基于对象的。
在查看按位操作时,Java 使用原始数据类型,由于没有装箱拆箱操作和包装器作为抽象层,可以说速度更快。因此,在每次迭代时查看您的代码,python 将整数重新包装为整数类型的对象,而 Java 没有。
但同样,我不会想当然地认为 Java 总是比 Python 快。这取决于您正在使用哪个库以及您要解决哪个问题!
推荐阅读
- alert - 基于线条颜色的警报
- php - (从 PHP 切换到 NODE) - 如何与前端通信?
- bash - 将所有文件(位于不同文件夹中)放在一个文件中
- angular - 即使我按照文档中的说明进行操作,Angular 通知程序也不会加载 css,它适用于带有通知程序 6.0.1 的 Angular 9
- assembly - 如何在没有 c 库的情况下在汇编中打印浮点数?
- python - pandas 从具有连续差异 < n 的数据帧中过滤行
- php - php - 如何在 Laravel Eloquent 中使用复杂(如派生表和子查询)查询
- javascript - 解构赋值,但没有模式
- mysql - 1054,字段列表中的未知列“索引”
- javascript - 如何将过渡添加到 div 边框