mirror of
https://github.com/ruby/ruby.git
synced 2026-08-12 08:20:37 +08:00
Make block#[], block#yield, block#=== faster when inside a method and the block is a block parameter. Treat it like an optimized method just like block#call was already. This avoids the proc allocation unless the method is redefined. ``` Summary (YJIT disabled): ┌──────────────────────┬────────────┬────────────┬─────────────────────────────────┐ │ op │ before │ after │ speedup │ ├──────────────────────┼────────────┼────────────┼─────────────────────────────────┤ │ block.call (control) │ 8.287M i/s │ 8.298M i/s │ ~1.00× (unchanged, as expected) │ ├──────────────────────┼────────────┼────────────┼─────────────────────────────────┤ │ block[] │ 3.786M i/s │ 8.289M i/s │ ~2.19× │ ├──────────────────────┼────────────┼────────────┼─────────────────────────────────┤ │ block.yield │ 3.760M i/s │ 8.269M i/s │ ~2.20× │ └──────────────────────┴────────────┴────────────┴─────────────────────────────────┘ Summary (YJIT enabled) ┌──────────────────────┬─────────────┬─────────────┬────────────────────┐ │ op │ before │ after │ speedup │ ├──────────────────────┼─────────────┼─────────────┼────────────────────┤ │ block.call (control) │ 32.736M i/s │ 32.749M i/s │ ~1.00× (unchanged) │ ├──────────────────────┼─────────────┼─────────────┼────────────────────┤ │ block[] │ 9.112M i/s │ 32.012M i/s │ ~3.51× │ ├──────────────────────┼─────────────┼─────────────┼────────────────────┤ │ block.yield │ 9.119M i/s │ 32.683M i/s │ ~3.58× │ └──────────────────────┴─────────────┴─────────────┴────────────────────┘ ```
68 lines
1.4 KiB
C
68 lines
1.4 KiB
C
#ifndef INTERNAL_BOP_H /*-*-C-*-vi:se ft=c:*/
|
|
#define INTERNAL_BOP_H
|
|
|
|
#include "internal.h"
|
|
#include "ruby/internal/dllexport.h"
|
|
|
|
enum ruby_basic_operators {
|
|
BOP_PLUS,
|
|
BOP_MINUS,
|
|
BOP_MULT,
|
|
BOP_DIV,
|
|
BOP_MOD,
|
|
BOP_EQ,
|
|
BOP_EQQ,
|
|
BOP_LT,
|
|
BOP_LE,
|
|
BOP_LTLT,
|
|
BOP_AREF,
|
|
BOP_ASET,
|
|
BOP_LENGTH,
|
|
BOP_SIZE,
|
|
BOP_EMPTY_P,
|
|
BOP_NIL_P,
|
|
BOP_SUCC,
|
|
BOP_GT,
|
|
BOP_GE,
|
|
BOP_GTGT,
|
|
BOP_NOT,
|
|
BOP_NEQ,
|
|
BOP_MATCH,
|
|
BOP_FREEZE,
|
|
BOP_UMINUS,
|
|
BOP_MAX,
|
|
BOP_MIN,
|
|
BOP_HASH,
|
|
BOP_CALL,
|
|
BOP_AND,
|
|
BOP_OR,
|
|
BOP_CMP,
|
|
BOP_DEFAULT,
|
|
BOP_PACK,
|
|
BOP_INCLUDE_P,
|
|
BOP_YIELD,
|
|
|
|
BOP_LAST_
|
|
};
|
|
|
|
RUBY_EXTERN short ruby_vm_redefined_flag[BOP_LAST_];
|
|
|
|
/* optimize insn */
|
|
#define INTEGER_REDEFINED_OP_FLAG (1 << 0)
|
|
#define FLOAT_REDEFINED_OP_FLAG (1 << 1)
|
|
#define STRING_REDEFINED_OP_FLAG (1 << 2)
|
|
#define ARRAY_REDEFINED_OP_FLAG (1 << 3)
|
|
#define HASH_REDEFINED_OP_FLAG (1 << 4)
|
|
/* #define BIGNUM_REDEFINED_OP_FLAG (1 << 5) */
|
|
#define SYMBOL_REDEFINED_OP_FLAG (1 << 6)
|
|
#define TIME_REDEFINED_OP_FLAG (1 << 7)
|
|
#define REGEXP_REDEFINED_OP_FLAG (1 << 8)
|
|
#define NIL_REDEFINED_OP_FLAG (1 << 9)
|
|
#define TRUE_REDEFINED_OP_FLAG (1 << 10)
|
|
#define FALSE_REDEFINED_OP_FLAG (1 << 11)
|
|
#define PROC_REDEFINED_OP_FLAG (1 << 12)
|
|
|
|
#define BASIC_OP_UNREDEFINED_P(op, klass) (LIKELY((ruby_vm_redefined_flag[(op)]&(klass)) == 0))
|
|
|
|
#endif
|