I'm working on <https://github.com/nim-lang/Nim/pull/20897> which replaces the 
dispatcher using subtype checking with the vtable dispatcher. But in the 
benchmark <https://gist.github.com/ringabout/0752a22b2c85e737a66314bb61a470e6>, 
they behave as good as each other.

The old dispatcher gains performance boost from 
<https://github.com/nim-lang/Nim/pull/20781>, which optimizes the subtype 
checking to an O(1) operation. It also uses direct call, while the vtable 
implementation uses indirect call.

Are there other factors which affect the performance of the vtable 
implementation?

The c code of the vtable implementation
    
    
    static N_INLINE(void*, nimGetVTable)(void* p__0kHUBDcXPgMHMI8U9cXW5CQ, NI 
index__P0r4EXn3O3JcFkHGB9caIWg) {
            void* result;
            result = (void*)0;
            result = (*(*((TNimTypeV2**) 
(p__0kHUBDcXPgMHMI8U9cXW5CQ)))).vTable[index__P0r4EXn3O3JcFkHGB9caIWg];
            return result;
    }
    
    N_LIB_PRIVATE N_NIMCALL(void, 
bar__test_37)(tyObject_AcolonObjectType___FPPdkqOrYRgd8wXaW5PMrA* 
x__WXRew1WllMKXFDEhSGiRFw) {
    NIM_BOOL* nimErr_;
    {nimErr_ = nimErrorFlag();
            {
                    if (!(x__WXRew1WllMKXFDEhSGiRFw == 0)) goto LA3_;
                    chckNilDisp(x__WXRew1WllMKXFDEhSGiRFw);
            }
            goto LA1_;
            LA3_: ;
            {
                    void* T6_;
                    T6_ = (void*)0;
                    T6_ = nimGetVTable(x__WXRew1WllMKXFDEhSGiRFw, 0);
                    ((tyProc__k3wrRs2usSIRSHGJl0kTNQ) 
(T6_))(x__WXRew1WllMKXFDEhSGiRFw);
                    if (NIM_UNLIKELY(*nimErr_)) goto BeforeRet_;
            }
            LA1_: ;
            }BeforeRet_: ;
    }
    
    
    Run

The c code of the old implementation
    
    
    N_LIB_PRIVATE N_NIMCALL(void, 
bar__test_37)(tyObject_AcolonObjectType___FPPdkqOrYRgd8wXaW5PMrA* 
x__WXRew1WllMKXFDEhSGiRFw) {
    NIM_BOOL* nimErr_;
    {nimErr_ = nimErrorFlag();
            chckNilDisp(x__WXRew1WllMKXFDEhSGiRFw);
            {
                    if (!((x__WXRew1WllMKXFDEhSGiRFw) && 
(isObjDisplayCheck((*x__WXRew1WllMKXFDEhSGiRFw).Sup.m_type, 17, 796740352)))) 
goto LA3_;
                    if (x__WXRew1WllMKXFDEhSGiRFw && 
!isObjDisplayCheck((*x__WXRew1WllMKXFDEhSGiRFw).Sup.m_type, 17, 796740352)){ 
raiseObjectConversionError(); goto BeforeRet_;
                    }
                    
bar__test_68(((tyObject_A16colonObjectType___Ci9a9aS6PLwJzUVRMIkKuZyw*) 
(x__WXRew1WllMKXFDEhSGiRFw)));
                    if (NIM_UNLIKELY(*nimErr_)) goto BeforeRet_;
            }
            goto LA1_;
            LA3_: ;
            {
                    if (!((x__WXRew1WllMKXFDEhSGiRFw) && 
(isObjDisplayCheck((*x__WXRew1WllMKXFDEhSGiRFw).Sup.m_type, 16, 2169393664)))) 
goto LA6_;
                    if (x__WXRew1WllMKXFDEhSGiRFw && 
!isObjDisplayCheck((*x__WXRew1WllMKXFDEhSGiRFw).Sup.m_type, 16, 2169393664)){ 
raiseObjectConversionError(); goto BeforeRet_;
                    }
                    
bar__test_66(((tyObject_A15colonObjectType___SIFOUqo7KT6mWGYo09clVRg*) 
(x__WXRew1WllMKXFDEhSGiRFw)));
                    if (NIM_UNLIKELY(*nimErr_)) goto BeforeRet_;
            }
            goto LA1_;
            LA6_: ;
            {
                    if (!((x__WXRew1WllMKXFDEhSGiRFw) && 
(isObjDisplayCheck((*x__WXRew1WllMKXFDEhSGiRFw).Sup.m_type, 15, 2733143808)))) 
goto LA9_;
                    if (x__WXRew1WllMKXFDEhSGiRFw && 
!isObjDisplayCheck((*x__WXRew1WllMKXFDEhSGiRFw).Sup.m_type, 15, 2733143808)){ 
raiseObjectConversionError(); goto BeforeRet_;
                    }
                    
bar__test_64(((tyObject_A14colonObjectType___VqLodxpzWtaIyT4TUFQvfg*) 
(x__WXRew1WllMKXFDEhSGiRFw)));
                    if (NIM_UNLIKELY(*nimErr_)) goto BeforeRet_;
            }
    
    
    Run

Reply via email to