Windows: avoid importing encodings._win_cp_codecs and time at startup

Abierto Apto para principiantes
#161,510 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
82/100
Tipo de issue
Nueva funcionalidad
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
python
Área
performance

Línea de trabajo

El issue señala Lib/encodings/__init__.py y Lib/zipimport.py; lee los dos puntos de importación y su uso en win32_code_page_search_function y _parse_dostime. Compara los imports que se realizan al iniciar en Windows y ejecuta las pruebas indicadas de codec, zipimport, time, signal y sys. Se considera terminado cuando ambos imports se posponen hasta sus puntos de uso y mejora el comportamiento de inicio sin regresiones en las pruebas.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

OS-windows performance stdlib type-feature
Feature or enhancement

On Windows, python -c pass imports two modules that Linux doesn't, and neither is needed on most starts:

  • encodings/__init__.py imports create_win32_code_page_codec from encodings._win_cp_codecs at module level (since 3.14). It is only called from win32_code_page_search_function, for a cpNNN name with no codec module.
  • zipimport imports time at module level for time.mktime in _parse_dostime. On Windows, time module init runs _tzset, which calls GetTimeZoneInformation. The first call in a process costs about 1 ms here.

From -X importtime (3.14.4, self time, median of 15): _win_cp_codecs 0.5 ms, time 0.96 ms on Windows (0.07 ms on Linux).

Moving both imports into the functions that use them (patch below) made python -c pass 3.6 ms faster (38.4 -> 34.4 ms; 95% CI 3.1-4.2 ms over 300 interleaved runs, release build of 3.14.4 without PGO). Each change alone is worth about 2 ms (_win_cp_codecs 2.1, time 2.4).

test_codecs, test_zipimport, test_zipimport_support, test_time, test_signal and test_sys pass with the change (3.14.4 build).

Both imports are unchanged on main (2781ffe1f2). The change, against main:

patch
diff --git a/Lib/encodings/__init__.py b/Lib/encodings/__init__.py
index 04594ea..bbccb93 100644
--- a/Lib/encodings/__init__.py
+++ b/Lib/encodings/__init__.py
@@ -157,8 +157,6 @@ def search_function(encoding):
 codecs.register(search_function)
 
 if sys.platform == 'win32':
-    from ._win_cp_codecs import create_win32_code_page_codec
-
     def win32_code_page_search_function(encoding):
         encoding = encoding.lower()
         if not encoding.startswith('cp'):
@@ -173,6 +171,7 @@ if sys.platform == 'win32':
         except (OverflowError, OSError):
             return None
 
+        from ._win_cp_codecs import create_win32_code_page_codec
         return create_win32_code_page_codec(cp)
 
     codecs.register(win32_code_page_search_function)
diff --git a/Lib/zipimport.py b/Lib/zipimport.py
index 09a85f6..aae77df 100644
--- a/Lib/zipimport.py
+++ b/Lib/zipimport.py
@@ -16,7 +16,6 @@ import _frozen_importlib as _bootstrap  # for _verbose_message
 import _imp  # for check_hash_based_pycs
 import _io  # for open
 import marshal  # for loads
-import time  # for mktime
 
 __all__ = ['ZipImportError', 'zipimporter']
 
@@ -767,6 +766,8 @@ def _compile_source(pathname, source, module):
 # Convert the date/time values found in the Zip archive to a value
 # that's compatible with the time stamp stored in .pyc files.
 def _parse_dostime(d, t):
+    # Imported here: importing time at start-up costs a time zone lookup.
+    import time
     return time.mktime((
         (d >> 9) + 1980,    # bits 9..15: year
         (d >> 5) & 0xF,     # bits 5..8: month

I used GitHub Copilot (Claude Opus 5.5 model) to trace this, build and time the prototype, and draft this issue. The measurements were run on my machine.

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

Lenguaje dominante
Python
Estrellas
77.9k
Forks
37.1k
Merge medio
17 h 43 min
PR fusionados (30 d)
675

Preparar el entorno

Abrir en Codespaces

Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de python/cpython

Todos los issues de python/cpython

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.