{"id":2569,"library":"line-profiler","title":"Line-by-line profiler","description":"line_profiler is a module for doing line-by-line profiling of functions, providing detailed timing statistics for each line within selected functions. kernprof is a companion script that conveniently runs line_profiler or Python's standard library profilers. It is currently at version 5.0.2 and actively maintained, with a release cadence that includes regular bug fixes and feature enhancements.","status":"active","version":"5.0.2","language":"en","source_language":"en","source_url":"https://github.com/pyutils/line_profiler","tags":["profiling","performance","developer-tool","optimization"],"install":[{"cmd":"pip install line-profiler","lang":"bash","label":"Standard installation"},{"cmd":"pip install line-profiler[all]","lang":"bash","label":"With optional dependencies (e.g., 'rich' for enhanced output)"}],"dependencies":[{"reason":"Requires Python 3.8 or higher.","package":"python","optional":false},{"reason":"Optional dependency for rich (highlighted) console output when using kernprof with '-r' flag.","package":"rich","optional":true}],"imports":[{"note":"While older versions and kernprof's default behavior could inject `@profile` into builtins, explicit import is the modern and recommended way since v4.1.0 for better script compatibility when not profiling.","wrong":"from __builtins__ import profile","symbol":"profile","correct":"from line_profiler import profile"},{"note":"Used for programmatic control of profiling.","symbol":"LineProfiler","correct":"from line_profiler import LineProfiler"}],"quickstart":{"code":"import time\nfrom line_profiler import profile\nimport os\n\n@profile\ndef slow_function_one():\n    time.sleep(0.01)\n    [x * x for x in range(1000)] # This line will be profiled\n\n@profile\ndef slow_function_two(iterations):\n    data = []\n    for _ in range(iterations):\n        data.append(sum(range(100)))\n    time.sleep(0.02)\n\ndef main():\n    print('Starting profiling demo...')\n    slow_function_one()\n    slow_function_two(1000)\n    print('Profiling demo finished.')\n\nif __name__ == '__main__':\n    # Method 1: Run with environment variable (requires line_profiler to be imported and decorated)\n    #   To run: LINE_PROFILE=1 python my_script.py\n    #   Output will be printed to console and .lprof file generated.\n\n    # Method 2: Run directly via kernprof CLI (recommended for explicit control)\n    #   To run: kernprof -lvr my_script.py\n    #   -l enables line-by-line profiling\n    #   -v prints results to stdout\n    #   -r enables rich output (if 'rich' is installed)\n\n    # This block ensures the script is runnable even without explicit kernprof or env var\n    if os.environ.get('LINE_PROFILE') == '1':\n        main()\n    else:\n        # For direct execution without profiling enabled, or if kernprof handles execution\n        main()\n","lang":"python","description":"Create a file named `my_script.py` with the code above. To profile, you can either set the `LINE_PROFILE=1` environment variable and run `python my_script.py`, or use the `kernprof` command-line tool. The `kernprof -lvr my_script.py` command is recommended to enable line-by-line profiling, view results directly in the console (verbose), and utilize rich formatting if available."},"warnings":[{"fix":"Upgrade Python to 3.8 or newer, or pin `line-profiler<4.2.0`.","message":"Python 3.6 and 3.7 support was removed in version 4.2.0. Users on these Python versions must use an older version of line-profiler or upgrade their Python interpreter.","severity":"breaking","affected_versions":"<4.2.0"},{"fix":"Upgrade to `line-profiler>=5.0.1` to mitigate performance issues and ensure correct multiprocessing output on Python 3.14+.","message":"Version 5.0.0 introduced potential speed regressions (fixed in 5.0.1) and specifically had issues with 'duplicate or inconsistent profiler output under Python 3.14 when multiprocessing is used.' This was fixed in 5.0.1.","severity":"breaking","affected_versions":"5.0.0"},{"fix":"Interpret profiling results as relative performance indicators rather than absolute benchmarks. Run multiple times to average out variations.","message":"Profiling inherently adds overhead to your code's execution. The measured times reflect the profiled execution, not necessarily the exact performance without profiling. Be mindful of this when interpreting results.","severity":"gotcha","affected_versions":"All"},{"fix":"For concurrent code, consider using profilers designed for such environments (e.g., `yappi` for multi-threading) or carefully isolate parts to profile one at a time.","message":"line_profiler may produce unexpected or no results when profiling multi-threaded, multi-processing, or asynchronous (asyncio) code due to the nature of its tracing mechanism.","severity":"gotcha","affected_versions":"All"},{"fix":"Replace `enable()/disable()` with `enable_by_count()/disable_by_count()` for robust nested profiling.","message":"For programmatic control, directly calling `profiler.enable()` and `profiler.disable()` can be unsafe when nested. If you need nested profiling, use `profiler.enable_by_count()` and `profiler.disable_by_count()` instead.","severity":"gotcha","affected_versions":"All"},{"fix":"Ensure Cython extensions are built with absolute paths for profiling builds, or investigate specific Cython build configurations that resolve this.","message":"When profiling Cython extensions built with relative paths, `line_profiler` might fail to display the original source code along with profiling results.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-10T00:00:00.000Z","next_check":"2026-07-09T00:00:00.000Z"}