Skip to content

gh-114682: Use METH_METHOD calling convention in _decimal #115196

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed

gh-114682: Use METH_METHOD calling convention in _decimal #115196

wants to merge 7 commits into from

Conversation

neonene
Copy link
Contributor

@neonene neonene commented Feb 9, 2024

The following 115 methods in the _decimal module experimentally have METH_METHOD|METH_FASTCALL instead here to see a performance effect and the diff size (without docstr).

static PyMethodDef signaldict_methods[] = {
  {"copy", signaldict_copy, METH_NOARGS, NULL},
};

static PyMethodDef dec_methods[] = {
  /* Unary arithmetic functions, optional context arg */
  {"exp", dec_mpd_qexp, METH_VARARGS|METH_KEYWORDS, doc_exp},
  {"ln", dec_mpd_qln, METH_VARARGS|METH_KEYWORDS, doc_ln},
  {"log10", dec_mpd_qlog10, METH_VARARGS|METH_KEYWORDS, doc_log10},
  {"next_minus", dec_mpd_qnext_minus, METH_VARARGS|METH_KEYWORDS, doc_next_minus},
  {"next_plus", dec_mpd_qnext_plus, METH_VARARGS|METH_KEYWORDS, doc_next_plus},
  {"normalize", dec_mpd_qreduce, METH_VARARGS|METH_KEYWORDS, doc_normalize},
  {"to_integral", PyDec_ToIntegralValue_, METH_VARARGS|METH_KEYWORDS, doc_to_integral},
  {"to_integral_exact", PyDec_ToIntegralExact, METH_VARARGS|METH_KEYWORDS, doc_to_integral_exact},
  {"to_integral_value", PyDec_ToIntegralValue, METH_VARARGS|METH_KEYWORDS, doc_to_integral_value},
  {"sqrt", dec_mpd_qsqrt, METH_VARARGS|METH_KEYWORDS, doc_sqrt},

  /* Binary arithmetic functions, optional context arg */
  {"compare", dec_mpd_qcompare, METH_VARARGS|METH_KEYWORDS, doc_compare},
  {"compare_signal", dec_mpd_qcompare_signal, METH_VARARGS|METH_KEYWORDS, doc_compare_signal},
  {"max", dec_mpd_qmax, METH_VARARGS|METH_KEYWORDS, doc_max},
  {"max_mag", dec_mpd_qmax_mag, METH_VARARGS|METH_KEYWORDS, doc_max_mag},
  {"min", dec_mpd_qmin, METH_VARARGS|METH_KEYWORDS, doc_min},
  {"min_mag", dec_mpd_qmin_mag, METH_VARARGS|METH_KEYWORDS, doc_min_mag},
  {"next_toward", dec_mpd_qnext_toward, METH_VARARGS|METH_KEYWORDS, doc_next_toward},
  {"quantize", dec_mpd_qquantize, METH_VARARGS|METH_KEYWORDS, doc_quantize},
  {"remainder_near", dec_mpd_qrem_near, METH_VARARGS|METH_KEYWORDS, doc_remainder_near},

  /* Ternary arithmetic functions, optional context arg */
  {"fma", dec_mpd_qfma, METH_VARARGS|METH_KEYWORDS, doc_fma},

  /* Boolean functions, optional context arg */
  {"is_normal", dec_mpd_isnormal, METH_VARARGS|METH_KEYWORDS, doc_is_normal},
  {"is_subnormal", dec_mpd_issubnormal, METH_VARARGS|METH_KEYWORDS, doc_is_subnormal},

  /* Unary functions, no context arg */
  {"radix", dec_mpd_radix, METH_NOARGS, doc_radix},

  /* Unary functions, optional context arg for conversion errors */
  {"copy_abs", dec_mpd_qcopy_abs, METH_NOARGS, doc_copy_abs},
  {"copy_negate", dec_mpd_qcopy_negate, METH_NOARGS, doc_copy_negate},

  /* Unary functions, optional context arg */
  {"logb", dec_mpd_qlogb, METH_VARARGS|METH_KEYWORDS, doc_logb},
  {"logical_invert", dec_mpd_qinvert, METH_VARARGS|METH_KEYWORDS, doc_logical_invert},
  {"number_class", dec_mpd_class, METH_VARARGS|METH_KEYWORDS, doc_number_class},
  {"to_eng_string", dec_mpd_to_eng, METH_VARARGS|METH_KEYWORDS, doc_to_eng_string},

  /* Binary functions, optional context arg for conversion errors */
  {"compare_total", dec_mpd_compare_total, METH_VARARGS|METH_KEYWORDS, doc_compare_total},
  {"compare_total_mag", dec_mpd_compare_total_mag, METH_VARARGS|METH_KEYWORDS, doc_compare_total_mag},
  {"copy_sign", dec_mpd_qcopy_sign, METH_VARARGS|METH_KEYWORDS, doc_copy_sign},
  {"same_quantum", dec_mpd_same_quantum, METH_VARARGS|METH_KEYWORDS, doc_same_quantum},

  /* Binary functions, optional context arg */
  {"logical_and", dec_mpd_qand, METH_VARARGS|METH_KEYWORDS, doc_logical_and},
  {"logical_or", dec_mpd_qor, METH_VARARGS|METH_KEYWORDS, doc_logical_or},
  {"logical_xor", dec_mpd_qxor, METH_VARARGS|METH_KEYWORDS, doc_logical_xor},
  {"rotate", dec_mpd_qrotate, METH_VARARGS|METH_KEYWORDS, doc_rotate},
  {"scaleb", dec_mpd_qscaleb, METH_VARARGS|METH_KEYWORDS, doc_scaleb},
  {"shift", dec_mpd_qshift, METH_VARARGS|METH_KEYWORDS, doc_shift},

  /* Miscellaneous */
  {"as_tuple", PyDec_AsTuple, METH_NOARGS, doc_as_tuple},
  {"as_integer_ratio", dec_as_integer_ratio, METH_NOARGS, doc_as_integer_ratio},

  /* Special methods */
  {"__format__", dec_format, METH_VARARGS, NULL},
  {"__round__", PyDec_Round, METH_VARARGS, NULL},
  {"__ceil__", dec_ceil, METH_NOARGS, NULL},
  {"__floor__", dec_floor, METH_NOARGS, NULL},
  {"__trunc__", dec_trunc, METH_NOARGS, NULL},
};

static PyMethodDef context_methods[] = {
  /* Unary arithmetic functions */
  {"abs", ctx_mpd_qabs, METH_O, doc_ctx_abs},
  {"exp", ctx_mpd_qexp, METH_O, doc_ctx_exp},
  {"ln", ctx_mpd_qln, METH_O, doc_ctx_ln},
  {"log10", ctx_mpd_qlog10, METH_O, doc_ctx_log10},
  {"minus", ctx_mpd_qminus, METH_O, doc_ctx_minus},
  {"next_minus", ctx_mpd_qnext_minus, METH_O, doc_ctx_next_minus},
  {"next_plus", ctx_mpd_qnext_plus, METH_O, doc_ctx_next_plus},
  {"normalize", ctx_mpd_qreduce, METH_O, doc_ctx_normalize},
  {"plus", ctx_mpd_qplus, METH_O, doc_ctx_plus},
  {"to_integral", ctx_mpd_qround_to_int_, METH_O, doc_ctx_to_integral},
  {"to_integral_exact", ctx_mpd_qround_to_intx, METH_O, doc_ctx_to_integral_exact},
  {"to_integral_value", ctx_mpd_qround_to_int, METH_O, doc_ctx_to_integral_value},
  {"sqrt", ctx_mpd_qsqrt, METH_O, doc_ctx_sqrt},

  /* Binary arithmetic functions */
  {"add", ctx_mpd_qadd, METH_VARARGS, doc_ctx_add},
  {"compare", ctx_mpd_qcompare, METH_VARARGS, doc_ctx_compare},
  {"compare_signal", ctx_mpd_qcompare_signal, METH_VARARGS, doc_ctx_compare_signal},
  {"divide", ctx_mpd_qdiv, METH_VARARGS, doc_ctx_divide},
  {"divide_int", ctx_mpd_qdivint, METH_VARARGS, doc_ctx_divide_int},
  {"divmod", ctx_mpd_qdivmod, METH_VARARGS, doc_ctx_divmod},
  {"max", ctx_mpd_qmax, METH_VARARGS, doc_ctx_max},
  {"max_mag", ctx_mpd_qmax_mag, METH_VARARGS, doc_ctx_max_mag},
  {"min", ctx_mpd_qmin, METH_VARARGS, doc_ctx_min},
  {"min_mag", ctx_mpd_qmin_mag, METH_VARARGS, doc_ctx_min_mag},
  {"multiply", ctx_mpd_qmul, METH_VARARGS, doc_ctx_multiply},
  {"next_toward", ctx_mpd_qnext_toward, METH_VARARGS, doc_ctx_next_toward},
  {"quantize", ctx_mpd_qquantize, METH_VARARGS, doc_ctx_quantize},
  {"remainder", ctx_mpd_qrem, METH_VARARGS, doc_ctx_remainder},
  {"remainder_near", ctx_mpd_qrem_near, METH_VARARGS, doc_ctx_remainder_near},
  {"subtract", ctx_mpd_qsub, METH_VARARGS, doc_ctx_subtract},

  /* Binary or ternary arithmetic functions */
  {"power", ctx_mpd_qpow, METH_VARARGS|METH_KEYWORDS, doc_ctx_power},

  /* Ternary arithmetic functions */
  {"fma", ctx_mpd_qfma, METH_VARARGS, doc_ctx_fma},

  /* No argument */
  {"radix", ctx_mpd_radix, METH_NOARGS, doc_ctx_radix},

  /* Boolean functions */
  {"is_canonical", ctx_iscanonical, METH_O, doc_ctx_is_canonical},
  {"is_finite", ctx_mpd_isfinite, METH_O, doc_ctx_is_finite},
  {"is_infinite", ctx_mpd_isinfinite, METH_O, doc_ctx_is_infinite},
  {"is_nan", ctx_mpd_isnan, METH_O, doc_ctx_is_nan},
  {"is_normal", ctx_mpd_isnormal, METH_O, doc_ctx_is_normal},
  {"is_qnan", ctx_mpd_isqnan, METH_O, doc_ctx_is_qnan},
  {"is_signed", ctx_mpd_issigned, METH_O, doc_ctx_is_signed},
  {"is_snan", ctx_mpd_issnan, METH_O, doc_ctx_is_snan},
  {"is_subnormal", ctx_mpd_issubnormal, METH_O, doc_ctx_is_subnormal},
  {"is_zero", ctx_mpd_iszero, METH_O, doc_ctx_is_zero},

  /* Functions with a single decimal argument */
  {"_apply", PyDecContext_Apply_, METH_O, NULL},
  {"apply", PyDecContext_Apply, METH_O, doc_ctx_apply},

  {"canonical", ctx_canonical, METH_O, doc_ctx_canonical},
  {"copy_abs", ctx_mpd_qcopy_abs, METH_O, doc_ctx_copy_abs},
  {"copy_decimal", ctx_copy_decimal, METH_O, doc_ctx_copy_decimal},
  {"copy_negate", ctx_mpd_qcopy_negate, METH_O, doc_ctx_copy_negate},
  {"logb", ctx_mpd_qlogb, METH_O, doc_ctx_logb},
  {"logical_invert", ctx_mpd_qinvert, METH_O, doc_ctx_logical_invert},
  {"number_class", ctx_mpd_class, METH_O, doc_ctx_number_class},
  {"to_sci_string", ctx_mpd_to_sci, METH_O, doc_ctx_to_sci_string},
  {"to_eng_string", ctx_mpd_to_eng, METH_O, doc_ctx_to_eng_string},

  /* Functions with two decimal arguments */
  {"compare_total", ctx_mpd_compare_total, METH_VARARGS, doc_ctx_compare_total},
  {"compare_total_mag", ctx_mpd_compare_total_mag, METH_VARARGS, doc_ctx_compare_total_mag},
  {"copy_sign", ctx_mpd_qcopy_sign, METH_VARARGS, doc_ctx_copy_sign},
  {"logical_and", ctx_mpd_qand, METH_VARARGS, doc_ctx_logical_and},
  {"logical_or", ctx_mpd_qor, METH_VARARGS, doc_ctx_logical_or},
  {"logical_xor", ctx_mpd_qxor, METH_VARARGS, doc_ctx_logical_xor},
  {"rotate", ctx_mpd_qrotate, METH_VARARGS, doc_ctx_rotate},
  {"same_quantum", ctx_mpd_same_quantum, METH_VARARGS, doc_ctx_same_quantum},
  {"scaleb", ctx_mpd_qscaleb, METH_VARARGS, doc_ctx_scaleb},
  {"shift", ctx_mpd_qshift, METH_VARARGS, doc_ctx_shift},

  /* Miscellaneous */
  {"__copy__", context_copy_, METH_NOARGS, NULL},
  {"__reduce__", context_reduce, METH_NOARGS, NULL},
  {"copy", context_copy, METH_NOARGS, doc_ctx_copy},
  {"create_decimal", ctx_create_decimal, METH_VARARGS, doc_ctx_create_decimal},
  {"create_decimal_from_float", ctx_from_float, METH_O, doc_ctx_create_decimal_from_float},
};

@neonene
Copy link
Contributor Author

neonene commented Feb 10, 2024

Finished specifying METH_METHOD with AC. 89172a1 has no perf difference than main. I'm not confident in the arithmetic micro benchmark, though.

@neonene
Copy link
Contributor Author

neonene commented Feb 10, 2024

a7e00b2 puts PyType_GetModuleByDef() on each METH_MEHOD *_impl() function with some cleanup, which improves by about 6% for me.

@neonene
Copy link
Contributor Author

neonene commented Feb 10, 2024

1eeb531 replaces PyType_GetModuleByDef() in the *_impl functions with _PyType_GetModuleState(), which makes no change vs the previous commit (a7e00b2).

@neonene neonene closed this Mar 12, 2024
@neonene neonene deleted the meth_method branch March 12, 2024 02:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant