Python 与 Javascript 执行时间

问题描述 投票:0回答:2

我尝试使用 Javascript(Node.js) 和 Python 以及暴力算法来解决最大子数组。这是我的代码:

使用Python:

from datetime import datetime
from random import randint

arr = [randint(-1000,1000) for i in range(1000)]

def bruteForce(a):
  l = len(a)
  max = 0
  for i in range(l):
    sum = 0
    for j in range(i, l):
      sum += a[j]
      if(sum > max):
        max = sum
  return max

start = datetime.now()
bruteForce(arr)
end = datetime.now()

print(format(end-start))

和 JavaScript:

function randInt(start, end) {
    return Math.floor(Math.random() * (end - start + 1))
}

var arr = Array(1000).fill(randInt(-1000, 1000))

function bruteForce(arr) {
    var max = 0
    for (let i = 0; i < arr.length; i++) {
        var sum = 0
        for (let j = i; j < arr.length; j++) {
            sum += arr[j]
            max = Math.max(max, sum)
        }
    }
    return max
}

var start = performance.now()
bruteForce(arr)
var end = performance.now()
console.log(end - start)

Javascript 得到的结果约为 0.187 秒,而 python 得到的结果为 4.75 秒——大约慢了 25 倍。 是我的代码没有优化还是 python 真的比 javascript 慢吗?

javascript python
2个回答
16
投票

Python 本身并不比 Javascript 慢,它取决于实现。 这是比较 Node 和同样使用 JIT 的 PyPy 的结果:

> /pypy39/python brute.py
109.8594 ms N= 10000 result= 73682
> node brute.js
167.4442000091076 ms N= 10000 result= 67495

所以我们甚至可以说“Python 更快一些”...... 如果我们使用 Cython,带有一些类型提示,它会再次快很多 - 实际的全 C 速度:

> cythonize -a -i brutec.pyx
> python -c "import brutec"
69.28919999999998 ms N= 10000 result= 52040

为了使比较合理,我修复了您脚本中的一些问题:

  • 修复:js 脚本用单个随机中的所有相同值填充数组
  • 在 Python 中执行相同的基本循环 - 而不是使用范围迭代器(否则它会慢一些)
  • 使用相同的时间格式并将数组长度增加到10000 - 否则在分辨率和线程切换抖动方面时间太小

Python代码:

from time import perf_counter as clock
from random import randint

N = 10000
arr = [randint(-1000,1000) for i in range(N)]

def bruteForce(a):
  l = len(a)
  max = 0
  i = 0
  while i < l:
    sum = 0
    j = i
    while j < l:
      sum += a[j]
      if sum > max:
        max = sum
      j += 1
    i += 1
  return max

start = clock()
r = bruteForce(arr)
end = clock()
print((end - start) * 1000, 'ms', 'N=', N, 'result=', r)
##print(arr[:10])

JS代码:

var start = -1000, end = 1000, N=10000
var arr = Array.from({length: N}, 
    () => Math.floor(Math.random() * (end - start + 1) + start))

function bruteForce(arr) {
    var max = 0
    for (let i = 0; i < arr.length; i++) {
        var sum = 0
        for (let j = i; j < arr.length; j++) {
            sum += arr[j];
            max = Math.max(max, sum)
            //~ if (sum > max) max = sum;
        }
    }
    return max
}

var start = performance.now()
r = bruteForce(arr)
var end = performance.now()
console.log(end - start, 'ms', 'N=', N, 'result=', r)
//~ console.log(arr.slice(0, 10))

Cython(或 Python)的代码,丰富了一些类型提示:

import cython
from time import perf_counter as clock
from random import randint

N = 10000
arr = [randint(-1000,1000) for i in range(N)]

def bruteForce(arr):
  l: cython.int = len(arr)
  assert l <= 10000
  a: cython.int[10000] = arr  # copies mem from Python array
  max: cython.int = 0
  i: cython.int = 0
  while i < l:
    sum: cython.int = 0
    j: cython.int = i
    while j < l:
      sum += a[j]
      if sum > max:
        max = sum
      j += 1
    i += 1
  return max

start = clock()
r = bruteForce(arr)
end = clock()
print((end - start) * 1000, 'ms', 'N=', N, 'result=', r)
##print(arr[:10])

(在慢速笔记本上完成)


0
投票

我也检查了这一点,用js和Python循环和pandas,Js远比Python循环和pandas好,

我的代码:

JS: `

// Create a large dataset
const NUM_RECORDS = 1000*10000
const people = Array.from({ length: NUM_RECORDS }, (_, i) => ({ name: `Person ${i}`, age: i % 100, gender: i % 2 === 0 ? 'male' : 'female' }));

// Define filter parameters
const ageThreshold = 35;
const gender = 'male';

// JavaScript filter method
const jsStartTime = Date.now();
const filteredPeopleJS = people.filter(person => person.age > ageThreshold && person.gender === gender);
const jsEndTime = Date.now();
const jsTimeTaken = (jsEndTime - jsStartTime) / 1000; // Convert milliseconds to seconds

console.log("JavaScript filter method time:", jsTimeTaken, "seconds");

`

Python代码是: `

import pandas as pd
import numpy as np
import time


NUM_RECORDS = 1000 * 10000
people = [{'name': f'Person {i}', 'age': i % 100, 'gender': 'male' if i % 2 == 0 else 'female'} for i in range(NUM_RECORDS)]
df = pd.DataFrame(people)


age_threshold = 35
gender = 'male'


python_start_time = time.time()
filtered_people_python = list(filter(lambda person: person['age'] > age_threshold and person['gender'] == gender, people))
python_end_time = time.time()
python_time_taken = python_end_time - python_start_time

pandas_start_time = time.time()
filtered_people_pandas = df[(df['age'] > age_threshold) & (df['gender'] == gender)]
pandas_end_time = time.time()
pandas_time_taken = pandas_end_time - pandas_start_time

print("Python filter time:", python_time_taken)
print("Pandas time:", pandas_time_taken)

`

结果:JavaScript过滤方法时间:0.121秒, Python过滤时间:0.7254292964935303, 熊猫时间:0.4761631488800049

© www.soinside.com 2019 - 2024. All rights reserved.