Как стать автором
Обновить
2352.08
МТС
Про жизнь и развитие в IT

Python vs Java: кто быстрее и дешевле

Время на прочтение12 мин
Количество просмотров11K

Современный ИТ-рынок требует от компаний максимальной отдачи при минимальных затратах. Бизнес ждет быстрых результатов, технические команды сталкиваются с дефицитом ресурсов, а выбор языка программирования может кардинально повлиять на оба этих фактора.

Возглавляя бэкенд-команду витрины в KION, я, Леша Жиряков, постоянно балансирую между скоростью вывода фичей и стабильностью работы системы. Сегодня решил перевести абстрактные технические дискуссии в конкретные цифры. А еще — поделиться расчетами, которые помогут принять экономически обоснованное решение: что выбрать для следующего проекта — Python или Java?

Ниже разберу:

В конце сделаю выводы: какой ЯП, на мой взгляд, лучше использовать в проектной и продуктовой разработке для приведенных мной выкладок.

Скорость разработки

И сразу начну с исследований по теме:

Исследование Лутца Прехельта, 2000 год. В нем 80 программистов решали одинаковую задачу на разных ЯП. Результат — разработчики на Python завершили задачу в среднем в 2,2 раза быстрее, чем разработчики на Java.

Исследование Рэя Байшахи, 2014 год. Проанализировали 729 проектов, 80 миллионов строк кода на GitHub и обнаружили, что Python требует значительно меньше кода для выполнения аналогичных задач. Результат — программисты на Python пишут в 2,5 раза меньше строк кода для эквивалентной функциональности по сравнению с Java.

Исследование Биссьянде, 2013 год. На этот раз взяли 100 000 проектов с открытым исходным кодом и оценили время, затраченное на разработку эквивалентных функциональных требований. Результат — на реализацию функциональных требований на Python уходит в среднем в 2–3 раза меньше времени, чем на Java.

Исследование Нанца, 2015 год. Анализировали 10 языков программирования на 7 задачах из коллекции Rosetta Code. Результат — программы на Python требуют в среднем в 2,7 раза меньше строк кода и в 1,9 раза меньше времени разработки по сравнению с Java.

Из приведенных данных ясно, что скорость разработки на Python выше. Но какие факторы приводят к такому результату?

  • Компактный синтаксис. Python требует меньше кода для выполнения тех же задач. Отсутствие фигурных скобок, точек с запятой и других синтаксических элементов делает код чище и понятнее.

  • Встроенные высокоуровневые структуры данных. Python предлагает мощные инструменты, такие как списки, словари и множества с богатым API, что позволяет решать многие задачи в одну строку.

  • Интерпретируемость. Отсутствие необходимости компиляции ускоряет цикл разработки — внесли изменения, сразу запустили код.

  • Богатая стандартная библиотека. Принцип «батарейки включены» значит, что многие задачи можно решить без установки дополнительных пакетов.

  • Экосистема библиотек. PyPI предлагает более 400 000 пакетов практически для любой задачи, а их установка через pip очень проста.

А теперь сравним количество строк кода на примере нескольких типичных задач:

1. Парсинг JSON-файла

Python:

import json

with open('data.json') as file:
    data = json.load(file)
    
print(data['key'])  # Доступ к данным

Количество строк: 5.

Java:

import org.json.JSONObject;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.IOException;

public class JsonParser {
    public static void main(String[] args) {
        try {
            String content = new String(Files.readAllBytes(Paths.get("data.json")));
            JSONObject jsonObject = new JSONObject(content);
            System.out.println(jsonObject.getString("key"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Количество строк: 14.

2. Обработка CSV-файла

Python:

import csv

with open('data.csv') as file:
    reader = csv.reader(file)
    for row in reader:
        print(row[0])  # Печать первого столбца

Количество строк: 5.

Java:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class CsvProcessor {
    public static void main(String[] args) {
        String line;
        try (BufferedReader br = new BufferedReader(new FileReader("data.csv"))) {
            while ((line = br.readLine()) != null) {
                String[] values = line.split(",");
                System.out.println(values[0]);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Количество строк: 15.

3. Реализация алгоритма быстрой сортировки

Python:

def quicksort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quicksort(left) + middle + quicksort(right)

sorted_array = quicksort([3, 6, 8, 10, 1, 2, 1])

Количество строк: 9.

Java:

import java.util.Arrays;

public class QuickSort {
    public static void main(String[] args) {
        int[] array = {3, 6, 8, 10, 1, 2, 1};
        quickSort(array, 0, array.length - 1);
        System.out.println(Arrays.toString(array));
    }
    
    public static void quickSort(int[] arr, int low, int high) {
        if (low < high) {
            int partitionIndex = partition(arr, low, high);
            
            quickSort(arr, low, partitionIndex - 1);
            quickSort(arr, partitionIndex + 1, high);
        }
    }
    
    private static int partition(int[] arr, int low, int high) {
        int pivot = arr[high];
        int i = low - 1;
        
        for (int j = low; j < high; j++) {
            if (arr[j] <= pivot) {
                i++;
                
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
        
        int temp = arr[i + 1];
        arr[i + 1] = arr[high];
        arr[high] = temp;
        
        return i + 1;
    }
}

Количество строк: 34.

4. HTTP-клиент с авторизацией

Python (с HTTPX):

import httpx

async def fetch_data():
    async with httpx.AsyncClient() as client:
        headers = {"Authorization": "Bearer your_token"}
        response = await client.get("https://api.example.com/data", headers=headers)
        return response.json()

Количество строк: 6.

Java:

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class HttpClientExample {
    public static void main(String[] args) {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://api.example.com/data"))
                .header("Authorization", "Bearer your_token")
                .GET()
                .build();
        
        try {
            HttpResponse<String> response = client.send(request, 
                    HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Количество строк: 22.

5. Асинхронная обработка событий

Python:

import asyncio

async def process_data(data):
    await asyncio.sleep(1)  # Имитация асинхронной операции
    return f"Обработано: {data}"

async def main():
    tasks = [process_data(i) for i in range(5)]
    results = await asyncio.gather(*tasks)
    for result in results:
        print(result)

if __name__ == "__main__":
    asyncio.run(main())

Количество строк: 13.

Java:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

public class AsyncExample {
    public static void main(String[] args) {
        List<CompletableFuture<String>> futures = new ArrayList<>();
        
        for (int i = 0; i < 5; i++) {
            final int index = i;
            futures.add(CompletableFuture.supplyAsync(() -> {
                try {
                    Thread.sleep(1000); // Имитация асинхронной операции
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                return "Обработано: " + index;
            }));
        }
        
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
            .thenRun(() -> 
                futures.forEach(f -> {
                    try {
                        System.out.println(f.get());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                })
            ).join();
    }
}

Количество строк: 28.

Собрал таблицу со сравнением скорости разработки:

Задача

Строк на Python

Строк на Java

Соотношение
Java и Python

Парсинг JSON-файла

5

15–20

~3–4x

Простой веб-сервер

8

30–40

~4–5x

Подключение к БД и выполнение запроса

7

25–30

~3,5–4x

Обработка CSV-файла

4

15–20

~4–5x

Реализация алгоритма быстрой сортировки

10

25–30

~2,5–3x

HTTP-клиент с авторизацией

12

35–45

~3–3,8x

Многопоточная обработка данных

15

45–60

~3–4x

Создание и обучение простой ML-модели

10

50–70

~5–7x

Работа с регулярными выражениями

3

8–10

~2,7–3,3x

REST API (базовый CRUD)

20

60–80

~3–4x

Реализация класса с инкапсуляцией

8

15–20

~1,9–2,5x

Асинхронная обработка событий

12

35–45

~2,9–3,8x

Получается, в среднем Python требует в 2–4 раза меньше кода для решения типичных задач, а это напрямую влияет на скорость разработки и читаемость кода. Поэтому его чаще выбирают для быстрой разработки прототипов, скриптов и для проектов, где максимально важна скорость вывода на рынок.

Теперь подытожим. По исследованиям, которые я привел выше, понятно, что разработка на Python в 2–3 раза быстрее, чем на Java. И это только простые примеры — со сложными разница будет больше.

Меньше кода — больше скорость

 «Чем меньше кода, тем легче его изменять» — так звучит один из фундаментальных принципов в современной разработке ПО. Давайте разбираться, почему это утверждение верно и какие практические выводы из него можно сделать.

1. Объем кода напрямую влияет на когнитивную нагрузку разработчика.

Когда разработчик вносит изменения, ему нужно держать в голове структуру программы, взаимосвязи между компонентами и возможные побочные эффекты изменений. Если уменьшить объем кода, снизится и объем информации, которую нужно анализировать и учитывать.

2. Каждая строка кода — потенциальное место для ошибки.

Формула проста:

Вероятность ошибок ≈ количество строк кода × сложность каждой строки

Меньший объем кода автоматически уменьшает первый множитель в этом уравнении. Результат — меньше багов.

3. С ростом кодовой базы возрастает количество потенциальных взаимодействий между компонентами. Каждая дополнительная тысяча строк кода увеличивает вероятность появления ошибок примерно на 2–5% в зависимости от сложности системы.

4. Большой объем кода приводит к накоплению «технического долга» — ситуации, когда для поддержания работоспособности системы нужно все больше и больше времени и ресурсов. При этом вносить изменения — всегда рискованно.

5. В компактном коде изменения обычно более локализованы. Тут меньше мест, где нужно обновлять одну и ту же логику, и ниже вероятность «забыть» обновить какую-то часть кода. А еще — меньше конфликтов при слиянии веток (merge conflicts).

В сфере разработки программного обеспечения давно известно, что код читают значительно чаще, чем пишут. Код на Python короче, чем на Java, минимум в три раза. Что это значит:

  • Код легче поддерживать и изменять с точки зрения когнитивной нагрузки на разработчика. Необязательно нанимать сеньора, чтобы он мог разобраться в проекте.

  • Развитие и поддержка обходятся дешевле.

Исследование Роберта Гласса в книге Facts and Fallacies of Software Engineering показало, что на поддержку кода, включая чтение, понимание и модификацию, уходит примерно в 4–5 раз больше времени, чем на его первоначальное написание.

Битва титанов, или Сравнение производительности

Дальше покажу, как Python и Java справляются с задачами в реальных сценариях. Использовать буду Python 3.11.

Бенчмарки веб-серверов

RPS (Requests Per Second) для простых ответов

Возьму популярные фреймворки: FastAPI (Python) и Spring Boot (Java). При тестировании простых эндпоинтов, возвращающих JSON {"message": "Hello World"}, результаты выглядят так:

Фреймворк

RPS (запросов в секунду)

Средняя задержка

FastAPI (Uvicorn)

~9 000–12 000

~5–8 мс

Spring Boot

~25 000–30 000

~2–4 мс

Как видим, Java со Spring Boot демонстрирует примерно в 2,5–3 раза более высокую пропускную способность.

Пример с кодом:

Python:

# FastAPI пример
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def read_root():
    return {"message": "Hello World"}

Java:

// Spring Boot пример
@RestController
public class HelloController {
    @GetMapping("/")
    public Map<String, String> hello() {
        return Map.of("message", "Hello World");
    }
}

Парсинг JSON-файла

Для сравнения парсинга JSON обработаем файл размером 100 Мб со вложенными структурами:

Язык/библиотека

Время парсинга (секунды)

Использование памяти

Python (json)

~1,8–2,2

~300–350 Мб

Python (ujson)

~0,9–1,1

~300–350 Мб

Java (Jackson)

~0,5–0,7

~200–250 Мб

Java с библиотекой Jackson обрабатывает JSON примерно в 2–4 раза быстрее стандартной библиотеки Python и использует меньше памяти. Даже с ускоренной библиотекой ujson Python все равно отстает.

Пример:

Python:

# Python пример парсинга
import json
import time

start_time = time.time()
with open("large_file.json", "r") as f:
    data = json.load(f)
print(f"Parsing took {time.time() - start_time} seconds")

Java:

// Java пример парсинга
ObjectMapper mapper = new ObjectMapper();
long startTime = System.currentTimeMillis();
JsonNode data = mapper.readTree(new File("large_file.json"));
System.out.println("Parsing took " + 
    (System.currentTimeMillis() - startTime) / 1000.0 + " seconds");

Java предсказуемо выигрывает у Python в чистой производительности, демонстрируя в 2–4 раза лучшие показатели в типичных веб-сценариях. Но современные Python-фреймворки вроде FastAPI сокращают этот отрыв, особенно в асинхронных задачах. К тому же отставание в производительности можно ликвидировать «железом», просто увеличив количество подов в кубере.

Больше публикаций с бенчмарками и сравнениями Python и Java:

Циклы обновления ПО

Прежде чем приступить к самому интересному — расчетам, давайте поймем, сколько в среднем служит софт.

Исследование Forrester Research показывает, что типичный жизненный цикл корпоративного программного обеспечения составляет:

  • 7–10 лет до полного переписывания в крупных корпоративных системах ERP, CRM;

  • 4–7 лет во внутренних бизнес-приложениях;

  • 2–4 года в потребительских веб-приложениях.

А вот данные из отчета McKinsey & Company Developer Velocity Index:

  • компании, использующие микросервисы, обновляют отдельные компоненты каждые 2–4 недели и полностью переписывают их каждые 12–18 месяцев;

  • DevOps-ориентированные компании выпускают обновления в 46 раз чаще с циклом переписывания 18–24 месяца;

  • традиционные модели разработки: обновление каждые 3–6 месяцев, переписывание каждые 5–8 лет.

Но в каких случаях код действительно нужно переписывать? В исследовании CAST проанализировали более 1,3 миллиарда строк кода, а потом выявили факторы, которые приводят к необходимости переписать код:

  • технический долг превышает 25% от стоимости разработки — точка, после которой поддержка становится дороже переписывания;

  • устаревание технологий — 78% решений о переписывании связаны с устаревшими технологиями;

  • безопасность — 42% случаев полной переработки связаны с проблемами безопасности.

Согласно исследованию Stripe, ИТ-компании тратят около 42% времени разработчиков на поддержку существующего кода и устранение технического долга, а не на создание нового ПО.

Еще можно сказать об экономических аспектах переписывания кода: затраты на поддержку ПО после трехлетнего периода растут в среднем на 15–20% ежегодно, а к 7 году поддержка обходится в 3–4 раза дороже, чем разработка с нуля. И отраслевые различия — например, в финтехе и банковском секторе полное обновление базовых систем в среднем происходит каждые 10–15 лет, в розничной торговле и e-commerce — каждые 3–5 лет, а в медицинском ПО — 7–10 лет.

Если резюмировать все вышесказанное, в развивающейся компании софт переписывается или меняется в среднем раз в 5 лет.

Стоимость инфраструктуры

В зависимости от модели оплаты — за потребленные или за выделенные ресурсы — цены на инфраструктуру могут варьироваться в пределах 10–15%. Возьмем средние показатели за месяц в 2025 году:

CPU

225,00 ₽

за ядро

RAM

180,00 ₽

за Гб

SSD fast

3,50 ₽

за Гб

Кажется, все уже стало понятно. Но доведу дело до конца — посчитаю стоимость разработчика. Допустим, у нас есть сеньор-разработчик на Python и такой же на Java с зарплатой 300 000 рублей на руки. Сколько компания платит на самом деле?

Если зарплата на руки 300 000 рублей, компания платит 448 275,87
Если зарплата на руки 300 000 рублей, компания платит 448 275,87

Что мы имеем:

  • скорость разработки на Python в три раза быстрее, чем на Java;

  • Java производительней Python в среднем в три раза;

  • стоимость ядра CPU — 225 рублей;

  • стоимость потребления памяти примерно на одном уровне;

  • стоимость разработчика — 450 000 рублей в месяц.

Задача, которую Python-разработчик сделает за месяц, будет стоить 450 000 рублей. В то же время Java-разработка обойдется в 1 350 000 рублей, application на Java будет в три раза быстрее.

Допустим, нам нужно обрабатывать 10 000 RPS, и на Python мы держим одним ядром 500 RPS. То есть не просто принять и записать в кафку, а асинхронно сходить в другие микросервисы, повзаимодействовать с другими API, получить ответы, десериализовать и применить бизнес-логику. Нам понадобится 20 ядер — это 5 000 рублей в месяц на инфраструктуру для Python-стека при оплате 250 рублей за ядро. Для Java нам понадобится 7 ядер, ведь он быстрее Python в 3 раза. Тогда получится 1 500 RPS на ядро. То есть 1 750 рублей в месяц на инфраструктуру для Java-стека.

Разница в затратах на оплату труда Python- и Java-разработчика — 900 000 рублей. То есть разрабатывая код на Java, мы тратим на 900 000 рублей больше. При этом экономим на инфраструктуре 3 250 рублей каждый месяц. Получается, Java сравняется по затратам c Python за 276 месяцев — это 23 года. Учитывая, что софт переписывается в среднем каждые пять лет, инвестиции не отобьются.

Теперь к выводам

При проектной разработке и условии, что после сдачи код никогда не будет меняться, затраты на Java-стек выходят в ноль по сравнению с Python за 5 лет при 50 000 RPS. Если взять горизонт окупаемости и цикла обновления софта в 2,5 года, то Java-стек окупается при 100 000 RPS. Это без учета поддержки, доработок, новых фич и большего ФОТ для Java-специалистов. То есть сценарий маловероятный. А с учетом того, что каждая новая версия Python получает прирост производительности благодаря проекту faster CPython, окупаемость Java-стека под еще большим вопросом.

Итак, Python сокращает затраты на разработку в 3 раза по сравнению c Java. Для продуктового подхода выгоднее выбирать именно его, ведь работа над продуктом не прекращается, и с кодом нужно работать постоянно. Для проектного подхода Python подойдет, если нагрузка меньше 100 000 RPS и вы не планируете поддерживать код.

Когда лучше выбрать Java:

  • Мобильная разработка. Хотя есть фреймворки вроде Kivy или BeeWare, Python не основной язык для iOS и Android. Для мобильных приложений обычно выбирают Swift, Kotlin или кроссплатформенные решения на JavaScript. Экосистема Android SDK оптимизирована для Java и Kotlin и дает лучшую производительность и доступ к нативным API. Компиляция в байт-код на Java VM в скорости превосходит интерпретируемый Python.

  • Низкоуровневое программирование. Для драйверов устройств, встраиваемых систем с ограниченными ресурсами, операционных систем Python не подходит из-за уровня абстракции и потребления ресурсов. Java предлагает прямой доступ к системным ресурсам через JNI (Java Native Interface) и позволяет интегрировать C/C++-код. Статическая типизация Java минимизирует ошибки времени выполнения, которые критичны для встраиваемых систем. У Java меньший накладной расход памяти и более предсказуемое управление ресурсами, так что в этой области это лучшее решение.

  • Игры с высокими требованиями к графике. Хотя есть библиотеки вроде PyGame, для AAA-игр Python не используется. Java дает лучшую производительность в графически интенсивных приложениях благодаря прямому доступу к OpenGL через библиотеки вроде LWJGL. Эффективная многопоточность Java, в отличие от ограничений GIL в Python, позволяет полностью использовать многоядерные процессоры. Развитая экосистема инструментов для оптимизации и профилирования — то, что нужно для высокопроизводительных игр.

И напоследок пара слов о Python для enterprise-разработки. В индустрии есть мнение, что на Python можно писать только скрипты и прототипы, а для чего-то более серьезного он не годится. Эта тема тянет на отдельную публикацию — и в ближайшее время я ею займусь. Пока скажу, что современный Python предлагает полноценный набор инструментов enterprise-уровня. Мы в KION используем его для бэкенда витрин, собираем персонализированные витрины в реалтайме и применяем к ним больше 60 бизнес-правил — и нас все устраивает.

Говорить об этом я мог бы еще долго, но текст и так получился объемным. Кому интересно продолжить тему, добро пожаловать в комментарии!

Теги:
Хабы:
+23
Комментарии99

Полезные ссылки

Как я учился на аналитика данных

Уровень сложностиПростой
Время на прочтение5 мин
Количество просмотров7.2K
Всего голосов 18: ↑16 и ↓2+17
Комментарии3

Превращаем магию в технологию: как волонтеры МТС знакомили детей с цифровым миром

Время на прочтение4 мин
Количество просмотров327
Всего голосов 7: ↑5 и ↓2+6
Комментарии3

FreeIPA: как обнаружить атаку злоумышленника на любом этапе Кill Сhain. Часть 2

Время на прочтение14 мин
Количество просмотров1.4K
Всего голосов 9: ↑9 и ↓0+14
Комментарии2

Изоляция с помощью глобальных акторов в Swift Concurrency: варианты на примере @MainActor

Время на прочтение7 мин
Количество просмотров625
Всего голосов 6: ↑6 и ↓0+12
Комментарии0

Обходим подводные камни работы с UDA в коде на Lua для ScyllaDB: дружим Java-драйвер и пустые значения

Уровень сложностиСредний
Время на прочтение5 мин
Количество просмотров736
Всего голосов 6: ↑6 и ↓0+11
Комментарии0

Информация

Сайт
www.mts.ru
Дата регистрации
Дата основания
Численность
свыше 10 000 человек
Местоположение
Россия