{
  "schema": "balansis-site/benchmarks/1",
  "run": {
    "started_at_utc": "2026-09-08T18:58:41.621903+00:00",
    "finished_at_utc": "2026-09-08T18:58:44.587394+00:00",
    "generator": "scripts/generate-benchmarks.py",
    "generator_sha256": "01439b8fd653e7c3a63b09fd86dbecba78c397454aca3f7475b305d90c0c915b",
    "command": "python scripts/generate-benchmarks.py"
  },
  "environment": {
    "python": "3.12.3",
    "python_full": "3.12.3 (main, Jul 15 2026, 23:46:41) [GCC 13.3.0]",
    "numpy": "1.26.4",
    "balansis": "1.1.0",
    "balansis_installed_from": "PyPI wheel (site-packages)",
    "host": {
      "cpu_class": "Intel Xeon (серверный)",
      "cpu_count": 8,
      "platform_class": "Linux x86_64, glibc 2.39",
      "machine": "x86_64",
      "note": "разделяемый хост без изоляции CPU: абсолютные времена шумят, отношения между методами устойчивы"
    }
  },
  "provenance": {
    "pypi": {
      "available": true,
      "filename": "balansis-1.1.0-py3-none-any.whl",
      "url": "https://files.pythonhosted.org/packages/ab/4d/20871d9592ed3d61b47a27e3c8ab44f8ad8655439d91664be510746ee24f/balansis-1.1.0-py3-none-any.whl",
      "sha256_declared_by_pypi": "2445ae239cb21e48e5b267e5364e161cc6b89a0fbaef90160bf88bd3eae0b828",
      "size_bytes": 97881,
      "upload_time_utc": "2026-08-31T03:19:21.786970Z",
      "requires_python": "<4.0,>=3.10",
      "license": "AGPL-3.0-only",
      "python_classifiers": [
        "3",
        "3.10",
        "3.11",
        "3.12",
        "3.13",
        "3.14"
      ]
    },
    "wheel_check": {
      "verified": true,
      "sha256_downloaded": "2445ae239cb21e48e5b267e5364e161cc6b89a0fbaef90160bf88bd3eae0b828",
      "sha256_declared_by_pypi": "2445ae239cb21e48e5b267e5364e161cc6b89a0fbaef90160bf88bd3eae0b828",
      "installed_files_identical_to_wheel": 35,
      "installed_files_different": 0,
      "installed_files_missing": 0,
      "install_kind": "site-packages"
    },
    "source_checkout": {
      "commit": "91c406d72421d26d8a37fc8b9ff877d71ca143dd",
      "describe": "v1.1.0-1-g91c406d",
      "remote": "git@github.com:StudyLabPro/Balansis.git",
      "formal_tree_sha": "c12ba1e41eb99a975499c6df2e64e24c8a6f5539",
      "clean": true
    }
  },
  "cli": {
    "invocations": [
      {
        "command": "balansis doctor",
        "available": true,
        "exit_code": 0,
        "stdout": "{\"compensation\": 1e-12, \"operation\": \"compensated_add\", \"result\": 0.0, \"status\": \"ok\", \"version\": \"1.1.0\"}",
        "stderr_tail": ""
      },
      {
        "command": "balansis add 0.1 0.2 --json",
        "available": true,
        "exit_code": 0,
        "stdout": "{\"compensation\": 1.0, \"left\": 0.1, \"operation\": \"compensated_add\", \"result\": 0.30000000000000004, \"right\": 0.2}",
        "stderr_tail": ""
      }
    ]
  },
  "api_probe": {
    "sequence_sum_three_terms": {
      "input": [
        1e+16,
        1.0,
        -1e+16
      ],
      "balansis_total": 1.0,
      "balansis_compensation": 999999999999999.9,
      "builtin_sum": 1.0,
      "naive_loop": 0.0
    },
    "absolute_is_absolute": true,
    "divide_1_by_absolute": {
      "kind": "infinite",
      "reason": "finite_over_absolute"
    },
    "divide_saturate_value": 1000000000000.0,
    "two_sum_1e16_plus_1": {
      "sum": 1e+16,
      "error": 1.0,
      "exact": true
    }
  },
  "scenarios": [
    {
      "id": "aggregation",
      "title": "Агрегация со взаимным уничтожением слагаемых",
      "question": "Сумма 100 повторов блока [1e16, 1.0, -1e16]. Точный ответ — 100.",
      "exact_value": 100.0,
      "exact_repr": "100",
      "input": {
        "block": [
          1e+16,
          1.0,
          -1e+16
        ],
        "repeats": 100,
        "n_terms": 300
      },
      "results": [
        {
          "method": "naive_loop",
          "label": "наивный цикл float64",
          "value": 0.0,
          "abs_error": 100.0,
          "rel_error": 1.0,
          "correct_digits": 0.0,
          "exact": false,
          "timing": {
            "min_seconds": 3.1139934435486794e-06,
            "median_seconds": 3.2279931474477053e-06,
            "repeats": 25,
            "inner_calls": 1
          },
          "note": "порядок слева направо, как в любом учебном коде"
        },
        {
          "method": "builtin_sum",
          "label": "встроенный sum()",
          "value": 100.0,
          "abs_error": 0.0,
          "rel_error": 0.0,
          "correct_digits": 16.0,
          "exact": true,
          "timing": {
            "min_seconds": 1.1090014595538378e-06,
            "median_seconds": 1.1200027074664831e-06,
            "repeats": 25,
            "inner_calls": 1
          },
          "note": "с CPython 3.12 sum() применяет компенсацию Ноймайера — README Balansis всё ещё показывает для него 0.0, это устаревшее утверждение"
        },
        {
          "method": "numpy_sum",
          "label": "numpy.sum (попарное суммирование)",
          "value": 9.0,
          "abs_error": 91.0,
          "rel_error": 0.91,
          "correct_digits": 0.040958607678906384,
          "exact": false,
          "timing": {
            "min_seconds": 8.318980690091848e-06,
            "median_seconds": 8.775998139753938e-06,
            "repeats": 25,
            "inner_calls": 1
          },
          "note": "pairwise summation numpy, не компенсация"
        },
        {
          "method": "math_fsum",
          "label": "math.fsum",
          "value": 100.0,
          "abs_error": 0.0,
          "rel_error": 0.0,
          "correct_digits": 16.0,
          "exact": true,
          "timing": {
            "min_seconds": 1.5650002751499414e-06,
            "median_seconds": 1.5929981600493193e-06,
            "repeats": 25,
            "inner_calls": 1
          },
          "note": "точное суммирование Шевчука в C — прямой конкурент, не соломенное чучело"
        },
        {
          "method": "balansis_sequence_sum",
          "label": "Balansis Operations.sequence_sum",
          "value": 100.0,
          "abs_error": 0.0,
          "rel_error": 0.0,
          "correct_digits": 16.0,
          "exact": true,
          "timing": {
            "min_seconds": 3.930699313059449e-05,
            "median_seconds": 4.022702341899276e-05,
            "repeats": 25,
            "inner_calls": 1
          },
          "note": "Ноймайер поверх AbsoluteValue; возвращает и сумму, и величину компенсации"
        }
      ],
      "balansis_compensation_factor": 1e+17,
      "reading": "Наивный цикл теряет ответ полностью. Balansis его восстанавливает — но math.fsum восстанавливает тот же ответ и делает это быстрее. Отличие Balansis здесь не в цифре суммы, а в том, что вместе с суммой возвращается величина компенсации: сколько именно точности пришлось спасать."
    },
    {
      "id": "dot_product",
      "title": "Плохо обусловленное скалярное произведение",
      "question": "Скалярное произведение двух векторов длины 1000: точный ответ -0.530562605606728 при числе обусловленности ≈ 4.62e+18. Эталон вычислен в рациональной арифметике (fractions.Fraction), а не в float повышенной точности.",
      "exact_value": -0.5305626056067283,
      "exact_repr": "-4893576300353906275/9223372036854775808",
      "input": {
        "n": 1000,
        "condition_number": 4.615088976212499e+18,
        "seed": 20260908,
        "construction": "случайные векторы ±1e8; последний элемент b подобран так, чтобы сумма произведений оказалась порядка единицы"
      },
      "results": [
        {
          "method": "naive_loop",
          "label": "наивный цикл float64",
          "value": -32.0,
          "abs_error": 31.46943739439327,
          "rel_error": 59.31333467877216,
          "correct_digits": 0.0,
          "exact": false,
          "timing": {
            "min_seconds": 3.780997940339148e-05,
            "median_seconds": 3.804701555054635e-05,
            "repeats": 10,
            "inner_calls": 1
          },
          "note": ""
        },
        {
          "method": "numpy_dot",
          "label": "numpy.dot (BLAS)",
          "value": -32.0,
          "abs_error": 31.46943739439327,
          "rel_error": 59.31333467877216,
          "correct_digits": 0.0,
          "exact": false,
          "timing": {
            "min_seconds": 6.430200301110744e-07,
            "median_seconds": 6.780028343200684e-07,
            "repeats": 25,
            "inner_calls": 1
          },
          "note": ""
        },
        {
          "method": "math_fsum_products",
          "label": "math.fsum над произведениями",
          "value": -8.374969482421875,
          "abs_error": 7.844406876815147,
          "rel_error": 14.78507304118168,
          "correct_digits": 0.0,
          "exact": false,
          "timing": {
            "min_seconds": 5.189000512473285e-05,
            "median_seconds": 5.273050919640809e-05,
            "repeats": 10,
            "inner_calls": 1
          },
          "note": "точная сумма округлённых произведений — ошибка остаётся"
        },
        {
          "method": "balansis_dot2",
          "label": "Balansis dot2 (Ogita–Rump–Oishi)",
          "value": -0.5305626056067283,
          "abs_error": 4.4777549723651333e-17,
          "rel_error": 8.439635445556077e-17,
          "correct_digits": 16.0,
          "exact": false,
          "timing": {
            "min_seconds": 8.765098755247891e-05,
            "median_seconds": 9.17009892873466e-05,
            "repeats": 25,
            "inner_calls": 1
          },
          "note": "two_product ловит ошибку каждого произведения, math.fsum складывает всё точно"
        },
        {
          "method": "balansis_compensated_dot_product",
          "label": "Balansis numpy_integration.compensated_dot_product",
          "value": -0.5305626056067283,
          "abs_error": 4.4777549723651333e-17,
          "rel_error": 8.439635445556077e-17,
          "correct_digits": 16.0,
          "exact": false,
          "timing": {
            "min_seconds": 8.756900206208229e-05,
            "median_seconds": 9.00080194696784e-05,
            "repeats": 25,
            "inner_calls": 1
          },
          "note": "публичный numpy-мост, внутри тот же dot2"
        }
      ],
      "reading": "Здесь у стандартной библиотеки нет ответа: math.fsum складывает точно, но произведения уже округлены до вызова. Это тот случай, ради которого компенсированная арифметика и существует — и цена за неё видна в колонке времени."
    },
    {
      "id": "softmax",
      "title": "Softmax на логитах, выходящих за диапазон float64",
      "question": "softmax([1000, 1000, 999, -1000]) — exp(1000) переполняет float64.",
      "exact_repr": [
        "0.4223187982515182",
        "0.4223187982515182",
        "0.15536240349696362",
        "0.0"
      ],
      "reference": {
        "method": "decimal.Decimal.exp с 60 значащими цифрами, сумма и деление там же",
        "significant_digits": 60,
        "note": "эталон на 40+ порядков точнее float64, поэтому ошибки участников интерпретируемы вплоть до последнего бита"
      },
      "input": {
        "logits": [
          1000.0,
          1000.0,
          999.0,
          -1000.0
        ]
      },
      "results": [
        {
          "method": "naive_numpy",
          "label": "np.exp(x)/sum — без сдвига",
          "values": [
            "nan",
            "nan",
            "nan",
            0.0
          ],
          "max_abs_error": null,
          "has_nan": true,
          "timing": {
            "min_seconds": 4.039000486955047e-06,
            "median_seconds": 4.20399010181427e-06,
            "repeats": 25,
            "inner_calls": 1
          }
        },
        {
          "method": "shifted_numpy",
          "label": "np.exp(x - max)/sum — стандартный приём",
          "values": [
            0.4223187982515182,
            0.4223187982515182,
            0.15536240349696362,
            0.0
          ],
          "max_abs_error": 1.2382666970114224e-17,
          "has_nan": false,
          "timing": {
            "min_seconds": 3.322988050058484e-06,
            "median_seconds": 3.5940029192715883e-06,
            "repeats": 25,
            "inner_calls": 1
          }
        },
        {
          "method": "balansis_compensated_softmax",
          "label": "Balansis compensated_softmax",
          "values": [
            0.4223187982515182,
            0.4223187982515182,
            0.15536240349696362,
            0.0
          ],
          "max_abs_error": 1.2382666970114224e-17,
          "has_nan": false,
          "timing": {
            "min_seconds": 5.484005669131875e-06,
            "median_seconds": 5.707988748326898e-06,
            "repeats": 25,
            "inner_calls": 1
          }
        }
      ],
      "long_vector": {
        "n": 20000,
        "question": "20 000 логитов в диапазоне ±40: ошибка копится в знаменателе.",
        "numpy_shifted_max_abs_error": 4.770724761086887e-19,
        "balansis_max_abs_error": 4.770724761086887e-19,
        "numpy_timing": {
          "min_seconds": 9.537598816677928e-05,
          "median_seconds": 9.562699415255338e-05,
          "repeats": 10,
          "inner_calls": 1
        },
        "balansis_timing": {
          "min_seconds": 0.0038889679999556392,
          "median_seconds": 0.003955101492465474,
          "repeats": 10,
          "inner_calls": 1
        }
      },
      "reading": "Наивная реализация даёт NaN. Но сдвиг на максимум — приём, известный любому инженеру ML, и он тоже даёт правильный ответ. Balansis делает тот же сдвиг плюс суммирование знаменателя по Кэхэну: выигрыш здесь — в последних битах и в том, что приём не нужно помнить, а не в разнице между ответом и NaN."
    },
    {
      "id": "ledger",
      "title": "Двойная запись: баланс обязан быть нулём",
      "question": "Четыре проводки, сумма которых математически равна нулю — в двух масштабах величин.",
      "variants": [
        {
          "case": "exactly_representable",
          "title": "суммы, точно представимые в двоичном float64 (128.5, 0.25)",
          "amounts": [
            "128.5",
            "0.25",
            "-128.5",
            "-0.25"
          ],
          "exact_repr": "0",
          "results": [
            {
              "method": "float_accumulation",
              "label": "накопление в float64",
              "value": 0.0,
              "is_exact_zero": true,
              "timing": {
                "min_seconds": 4.440080374479294e-07,
                "median_seconds": 4.6900822781026363e-07,
                "repeats": 25,
                "inner_calls": 1
              }
            },
            {
              "method": "decimal_accumulation",
              "label": "decimal.Decimal",
              "value": "0.00",
              "is_exact_zero": true,
              "timing": {
                "min_seconds": 3.4700497053563595e-07,
                "median_seconds": 3.7800054997205734e-07,
                "repeats": 25,
                "inner_calls": 1
              }
            },
            {
              "method": "balansis_ledger",
              "label": "Balansis Ledger.balance()",
              "value": 0.0,
              "is_exact_zero": true,
              "structural_zero": true,
              "timing": {
                "min_seconds": 9.91899287328124e-06,
                "median_seconds": 1.0260991984978318e-05,
                "repeats": 15,
                "inner_calls": 1
              }
            }
          ]
        },
        {
          "case": "within_float64",
          "title": "обычные денежные суммы (12345.67), не представимые в двоичном float точно",
          "amounts": [
            "12345.67",
            "0.02",
            "-12345.67",
            "-0.02"
          ],
          "exact_repr": "0",
          "results": [
            {
              "method": "float_accumulation",
              "label": "накопление в float64",
              "value": 4.365570405173713e-13,
              "is_exact_zero": false,
              "timing": {
                "min_seconds": 4.5201159082353115e-07,
                "median_seconds": 4.819885361939669e-07,
                "repeats": 25,
                "inner_calls": 1
              }
            },
            {
              "method": "decimal_accumulation",
              "label": "decimal.Decimal",
              "value": "0.00",
              "is_exact_zero": true,
              "timing": {
                "min_seconds": 3.2997922971844673e-07,
                "median_seconds": 3.449968062341213e-07,
                "repeats": 25,
                "inner_calls": 1
              }
            },
            {
              "method": "balansis_ledger",
              "label": "Balansis Ledger.balance()",
              "value": 4.365570405173713e-13,
              "is_exact_zero": false,
              "structural_zero": false,
              "timing": {
                "min_seconds": 9.866023901849985e-06,
                "median_seconds": 1.0373012628406286e-05,
                "repeats": 15,
                "inner_calls": 1
              }
            }
          ]
        },
        {
          "case": "beyond_float64",
          "title": "суммы за пределами точности float64 (14 значащих цифр плюс копейки)",
          "amounts": [
            "10000000000000.01",
            "0.02",
            "-10000000000000.01",
            "-0.02"
          ],
          "exact_repr": "0",
          "results": [
            {
              "method": "float_accumulation",
              "label": "накопление в float64",
              "value": -0.0004687500000000004,
              "is_exact_zero": false,
              "timing": {
                "min_seconds": 6.310001481324434e-07,
                "median_seconds": 6.550108082592487e-07,
                "repeats": 25,
                "inner_calls": 1
              }
            },
            {
              "method": "decimal_accumulation",
              "label": "decimal.Decimal",
              "value": "0.00",
              "is_exact_zero": true,
              "timing": {
                "min_seconds": 3.3699325285851955e-07,
                "median_seconds": 3.490131348371506e-07,
                "repeats": 25,
                "inner_calls": 1
              }
            },
            {
              "method": "balansis_ledger",
              "label": "Balansis Ledger.balance()",
              "value": -0.0004687500000000004,
              "is_exact_zero": false,
              "structural_zero": false,
              "timing": {
                "min_seconds": 9.99998883344233e-06,
                "median_seconds": 1.0221003321930766e-05,
                "repeats": 15,
                "inner_calls": 1
              }
            }
          ]
        }
      ],
      "reading": "Прогон показал границу честнее, чем это описано в самом репозитории. Balansis.Ledger отвечает состоянием ABSOLUTE — структурным нулём, который нельзя перепутать с маленьким остатком, — но ровно тогда, когда и обычное сложение float даёт ноль: суммы должны быть точно представимы в двоичном float64. На «12345.67» и тем более на «10000000000000.01» структурный ноль исчезает, и Ledger возвращает ту же ошибку, что и float, потому что Ledger.post_entry принимает Decimal и немедленно приводит его к float. Компенсация не восстанавливает то, что потеряно на входе. Вывод для практики: ценность Ledger — в типе ответа (ноль как состояние, а не как число), а точность на деньгах даёт Decimal, и Balansis его не заменяет."
    },
    {
      "id": "cancellation_signal",
      "title": "Сигнал о потере точности — не то же самое, что восстановленное значение",
      "question": "compensated_add(1e16, -1e16): математически точный ответ здесь — ноль.",
      "input": {
        "a": 1e+16,
        "b": -1e+16
      },
      "float_reference": {
        "expression": "(1e16 + 1.0) - 1e16",
        "value": 0.0,
        "comment": "единица теряется при округлении 1e16 + 1.0 — до всякого вычитания"
      },
      "results": [
        {
          "method": "float_subtraction",
          "label": "1e16 + (-1e16) в float64",
          "value": 0.0,
          "exact_answer": 0.0,
          "equals_exact": true
        },
        {
          "method": "balansis_compensated_add",
          "label": "Operations.compensated_add",
          "value": 2.0,
          "exact_answer": 0.0,
          "equals_exact": false,
          "compensation_factor": 5000000000000000.0,
          "magnitude_is_one_ulp": true
        }
      ],
      "reading": "Здесь Balansis намеренно отвечает не тем числом, которое верно математически. Точная разность равна нулю, и float64 её даёт; Balansis возвращает величину в один ULP от операнда — это флаг «в этом месте операнды настолько велики, что настоящая разность могла быть потеряна раньше», плюс большой коэффициент компенсации. Полезно, когда ноль опасно принимать за истину (следом идёт деление или логарифм). Вредно, если читать результат как «восстановленное значение»: это сигнал, а не восстановление. Ровно так это и нужно понимать в разделе README «Catastrophic Cancellation»."
    },
    {
      "id": "singular",
      "title": "Деление на ноль как состояние, а не как исключение",
      "question": "1/0, -1/0 и 0/0 — что возвращает язык и что возвращает Balansis.",
      "baseline": {
        "python_1_div_0": "ZeroDivisionError: float division by zero",
        "python_0_div_0": "ZeroDivisionError: float division by zero",
        "numpy_1_div_0": "inf",
        "numpy_0_div_0": "nan"
      },
      "results": [
        {
          "numerator": 1.0,
          "denominator": 0.0,
          "kind": "infinite",
          "reason": "finite_over_absolute",
          "compensation": 999999999999999.9,
          "numerical_value": "inf",
          "policies": {
            "propagate": {
              "kind": "infinite",
              "value": "inf",
              "event": "infinite"
            },
            "saturate": {
              "kind": "finite",
              "value": 1000000000000.0,
              "event": "finite"
            },
            "raise": {
              "raised": "ValueError",
              "message": "compensated_divide_policy produced singular ExtendedRatio(kind=infinite, reason=finite_over_absolute)"
            }
          }
        },
        {
          "numerator": -1.0,
          "denominator": 0.0,
          "kind": "infinite",
          "reason": "finite_over_absolute",
          "compensation": 999999999999999.9,
          "numerical_value": "-inf",
          "policies": {
            "propagate": {
              "kind": "infinite",
              "value": "-inf",
              "event": "infinite"
            },
            "saturate": {
              "kind": "finite",
              "value": -1000000000000.0,
              "event": "finite"
            },
            "raise": {
              "raised": "ValueError",
              "message": "compensated_divide_policy produced singular ExtendedRatio(kind=infinite, reason=finite_over_absolute)"
            }
          }
        },
        {
          "numerator": 0.0,
          "denominator": 0.0,
          "kind": "indeterminate",
          "reason": "absolute_over_absolute",
          "compensation": 999999999999999.9,
          "numerical_value": "nan",
          "policies": {
            "propagate": {
              "kind": "indeterminate",
              "value": "nan",
              "event": "indeterminate"
            },
            "saturate": {
              "kind": "indeterminate",
              "value": "nan",
              "event": "indeterminate"
            },
            "raise": {
              "raised": "ValueError",
              "message": "compensated_divide_policy produced singular ExtendedRatio(kind=indeterminate, reason=absolute_over_absolute)"
            }
          }
        }
      ],
      "reading": "Python бросает исключение и теряет знак; numpy тихо возвращает inf и nan с предупреждением, которое почти всегда отключено. Balansis возвращает типизированное состояние с направлением и причиной, а политика raise/propagate/saturate выбирается вызывающим кодом явно. Ровно эта семантика и доказана в Lean4 (файл ACT/ExtendedRatio.lean)."
    },
    {
      "id": "svd",
      "title": "SVD: что в ней действительно «компенсированное»",
      "question": "Матрица 24×24 с заданными сингулярными числами от 1 до 1e-14.",
      "input": {
        "n": 24,
        "planted_singular_values": "logspace(0, -14)"
      },
      "results": {
        "numpy_gesdd": {
          "reconstruction_error": 2.169135525007178e-15,
          "smallest_singular_value": 1.0010540378469623e-14,
          "largest_singular_value": 0.9999999999999993,
          "singular_value_rel_error_vs_planted": 0.0010540378469622762,
          "timing": {
            "min_seconds": 0.0017987139872275293,
            "median_seconds": 0.002366877975873649,
            "repeats": 3,
            "inner_calls": 1
          }
        },
        "act_jacobi": {
          "reconstruction_error": 5.395436096765123e-15,
          "smallest_singular_value": 1.001719656643311e-14,
          "largest_singular_value": 1.0000000000000027,
          "singular_value_rel_error_vs_planted": 0.0017196566433109596,
          "timing": {
            "min_seconds": 0.18805116499424912,
            "median_seconds": 0.18908504099817947,
            "repeats": 3,
            "inner_calls": 1
          }
        }
      },
      "reading": "Бэкенд numpy_gesdd — это буквально numpy.linalg.svd: выигрыша в точности у Balansis здесь нет и заявлять его было бы неправдой. Что добавлено — телеметрия по каждому сингулярному числу и явная политика на вырожденных состояниях. Бэкенд act_jacobi считает скалярные произведения через dot2; цена этого видна в таблице времени."
    },
    {
      "id": "object_cost",
      "title": "Сколько стоит компенсация",
      "question": "Во сколько раз операция Balansis медленнее эквивалентной операции float64.",
      "call_overhead": {
        "min_seconds": 1.5179975889623166e-08,
        "probe": {
          "min_seconds": 1.5179975889623166e-08,
          "median_seconds": 1.531501766294241e-08,
          "repeats": 25,
          "inner_calls": 200
        },
        "float_add_inline_seconds": 1.0524480021558702e-08,
        "note": "measure() вызывает функцию на каждую операцию; пустой вызов стоит столько же порядков, сколько сама скалярная операция. Колонка slowdown_net_x получена вычитанием этой величины из обеих сторон, float_add_inline_seconds — независимая проверка базовой строки через timeit со скомпилированным телом цикла."
      },
      "results": [
        {
          "operation": "сложение двух чисел",
          "float": {
            "min_seconds": 2.618500730022788e-08,
            "median_seconds": 2.7084897737950086e-08,
            "repeats": 25,
            "inner_calls": 200
          },
          "balansis": {
            "min_seconds": 9.695251355879008e-07,
            "median_seconds": 1.0273548832628875e-06,
            "repeats": 25,
            "inner_calls": 200
          },
          "balansis_label": "Operations.compensated_add",
          "slowdown_x": 37.025963921708104,
          "float_net_seconds": 1.1005031410604715e-08,
          "balansis_net_seconds": 9.543451596982776e-07,
          "slowdown_net_x": 86.71898553407557
        },
        {
          "operation": "конструирование значения",
          "float": {
            "min_seconds": 2.2939930204302074e-08,
            "median_seconds": 2.311004209332168e-08,
            "repeats": 25,
            "inner_calls": 200
          },
          "balansis": {
            "min_seconds": 8.995950338430702e-07,
            "median_seconds": 9.338650852441788e-07,
            "repeats": 25,
            "inner_calls": 200
          },
          "balansis_label": "AbsoluteValue.from_float (модель pydantic)",
          "slowdown_x": 39.21524720569391,
          "float_net_seconds": 7.759954314678907e-09,
          "balansis_net_seconds": 8.84415057953447e-07,
          "slowdown_net_x": 113.97168360649589
        },
        {
          "operation": "two_sum (примитив EFT)",
          "float": {
            "min_seconds": 2.60199885815382e-08,
            "median_seconds": 2.642496838234365e-08,
            "repeats": 25,
            "inner_calls": 200
          },
          "balansis": {
            "min_seconds": 7.93350045569241e-08,
            "median_seconds": 8.298491593450308e-08,
            "repeats": 25,
            "inner_calls": 200
          },
          "balansis_label": "_eft.two_sum — чистый float, без объектов",
          "slowdown_x": 3.0490022817771014,
          "float_net_seconds": 1.0840012691915033e-08,
          "balansis_net_seconds": 6.415502866730094e-08,
          "slowdown_net_x": 5.918353648713957
        },
        {
          "operation": "two_product (примитив EFT)",
          "float": {
            "min_seconds": 2.59549415204674e-08,
            "median_seconds": 2.6654888642951847e-08,
            "repeats": 25,
            "inner_calls": 200
          },
          "balansis": {
            "min_seconds": 1.4675504644401372e-07,
            "median_seconds": 1.537900243420154e-07,
            "repeats": 25,
            "inner_calls": 200
          },
          "balansis_label": "_eft.two_product — чистый float, без объектов",
          "slowdown_x": 5.654223737251979,
          "float_net_seconds": 1.0774965630844233e-08,
          "balansis_net_seconds": 1.3157507055439056e-07,
          "slowdown_net_x": 12.211182389087721
        }
      ],
      "vector_results": [
        {
          "operation": "поэлементное сложение массивов (n=100 000)",
          "float": {
            "min_seconds": 4.605000140145421e-05,
            "median_seconds": 4.78189904242754e-05,
            "repeats": 10,
            "inner_calls": 1
          },
          "balansis": {
            "min_seconds": 0.0009272170136682689,
            "median_seconds": 0.0010003915085690096,
            "repeats": 10,
            "inner_calls": 1
          },
          "balansis_label": "numpy_integration.compensated_array_add",
          "slowdown_x": 20.135005112920332,
          "float_net_seconds": 4.6034821425564585e-05,
          "balansis_net_seconds": 0.0009272018336923793,
          "slowdown_net_x": 20.141314878164707
        },
        {
          "operation": "скалярное произведение (n=100 000)",
          "float": {
            "min_seconds": 1.3747980119660497e-05,
            "median_seconds": 1.537898788228631e-05,
            "repeats": 10,
            "inner_calls": 1
          },
          "balansis": {
            "min_seconds": 0.011278088990366086,
            "median_seconds": 0.012076171493390575,
            "repeats": 10,
            "inner_calls": 1
          },
          "balansis_label": "numpy_integration.compensated_dot_product",
          "slowdown_x": 820.3451628677941,
          "float_net_seconds": 1.3732800143770873e-05,
          "balansis_net_seconds": 0.011278073810390197,
          "slowdown_net_x": 821.2508514154612
        },
        {
          "operation": "softmax (n=100 000)",
          "float": {
            "min_seconds": 0.0009014899842441082,
            "median_seconds": 0.0009182810026686639,
            "repeats": 10,
            "inner_calls": 1
          },
          "balansis": {
            "min_seconds": 0.02119198997388594,
            "median_seconds": 0.021407138498034328,
            "repeats": 10,
            "inner_calls": 1
          },
          "balansis_label": "numpy_integration.compensated_softmax",
          "slowdown_x": 23.507737572542467,
          "float_net_seconds": 0.0009014748042682186,
          "balansis_net_seconds": 0.021191974793910048,
          "slowdown_net_x": 23.508116581375614
        }
      ],
      "reading": "Замедление реально, и без накладных питоновского вызова оно измеряется сотнями раз для арифметики на объектах. Основная его часть — не математика, а объектная модель на pydantic: примитивы two_sum/two_product работают на голых float и стоят единицы. Если нужна скорость — берите слой _eft и numpy-мост, а не арифметику на AbsoluteValue."
    }
  ]
}
