पायथन में, उदाहरण के लिए @property डेकोरेटर का उपयोग करके एक वर्ग से व्युत्पन्न संपत्ति बनाना संभव है

class State():
    def __init__(self, fav_num_monday, fav_num_not_monday, is_monday):
        self.fav_num_monday = fav_num_monday
        self.fav_num_not_monday = fav_num_not_monday
        self.is_monday = is_monday

    @property
    def fav_num(self):
        return self.is_monday * self.fav_num_monday + \
            (1 - self.is_monday) * self.fav_num_not_monday

state = State(12, 5, 0)
print("Current favourite number: %d" % state.fav_num)

मेरा सवाल यह है कि सी में इसे हासिल करने का सबसे अच्छा तरीका क्या है (जहां गति अत्यंत महत्वपूर्ण है)। मैंने नीचे कुछ तरीके जोड़े हैं जिन्हें मैंने आजमाया है लेकिन मुझे यकीन नहीं है कि क्या वे बड़े कोडबेस में असर डाल सकते हैं। वे इस प्रकार हैं:

  1. बस हर बार पूरी अभिव्यक्ति लिखकर। पेशेवर: कोई अप्रत्याशित असर नहीं, कोई कोड/स्पीड पेनल्टी नहीं। विपक्ष: बदसूरत कोड, लिखने में लंबा समय लगता है।
  2. गेट फ़ंक्शन का उपयोग करना। पेशेवरों: कोड पढ़ने में आसान। विपक्ष: अक्षम कोड (1 से धीमा)।
  3. मैक्रो को परिभाषित करना। पेशेवरों: कोई कोड / गति दंड नहीं। कोड लिखने के लिए जल्दी। विपक्ष: बाद में संभावित नतीजे, कोड का पालन करना इतना आसान नहीं है।

उदाहरण कार्यक्रम नीचे है

#include <stdio.h>
#include <string.h>

#define state_fav_num  state.is_monday * state.fav_num_monday + (1 - state.is_monday) * state.fav_num_not_monday

struct State {
    int fav_num_monday;
    int fav_num_not_monday;
    int is_monday;
};

int get_state(struct State *state, char *property) {
    // Returns value of the property in state. 
    // Allows us to create derived properties also.
    if (!strncmp(property, "fav_num_monday", 14)) {
        return state->fav_num_monday;
    } else if (!strncmp(property, "fav_num_not_monday", 18)) {
        return state->fav_num_not_monday;
    } else if (!strncmp(property, "is_monday", 9)) {
        return state->is_monday;
    } else if (!strncmp(property, "fav_num", 7)) {
        return state->is_monday * state->fav_num_monday +
            (1 - state->is_monday) * state->fav_num_not_monday;
    }
}

int main() {
    // Set the state.
    struct State state;
    state.fav_num_monday = 12;
    state.fav_num_not_monday = 5;
    state.is_monday = 1;

    // Print favourite number in different ways.
    printf("\n1) Current favourite number is %d.",
        state.is_monday * state.fav_num_monday +
        (1 - state.is_monday) * state.fav_num_not_monday);

    printf("\n2) Current favourite number is %d.",
        get_state(&state, "fav_num"));

    printf("\n3) Current favourite number is %d.",
        state_fav_num);

    printf("\n");

    return 0;
}
2
rwolst 2 मार्च 2019, 13:40

1 उत्तर

सबसे बढ़िया उत्तर

आप static inline फ़ंक्शन के साथ, पठनीयता और प्रदर्शन के लिए दोनों दुनियाओं (फ़ंक्शन और मैक्रो) में से सर्वश्रेष्ठ प्राप्त कर सकते हैं।

आप आमतौर पर इसका उपयोग नहीं करेंगे, लेकिन यदि आप जानते हैं कि कंपाइलर अपने कोड को दूर करने जा रहा है, तो इसका उपयोग करना ठीक है। मेरे द्वारा उपयोग किया जाने वाला सामान्य नियम कोड की 3 या उससे कम पंक्तियाँ हैं, और फ़ंक्शन को अतिरिक्त प्रदर्शन की आवश्यकता होनी चाहिए।

उस ने कहा, आपका get_state static inline फ़ंक्शन के लिए (मेरी) आवश्यकताओं को पूरा नहीं करता है, लेकिन यदि आप केवल एक फ़ंक्शन को केवल fav_num प्राप्त करना चाहते हैं, तो यह समझ में आता है:

struct State {
    int     fav_num_monday;
    int     fav_num_not_monday;
    bool    is_monday;
};


static inline   int get_fav_num(const struct State *state)
{

    if (state->is_monday)
        return  state->fav_num_monday;
    else
        return  state->fav_num_not_monday;
}


int main(void)
{
    struct State state;
    int fav_num;

    state   = (struct State){
        .fav_num_monday     = 12;
        .fav_num_not_monday = 5;
        .is_monday          = 1;
    };

    // Print favourite number in different ways.
    printf("\n");
    if (state.is_monday)
        fav_num = state->fav_num_monday;
    else
        fav_num = state->fav_num_not_monday;
    printf("1) Current favourite number is %d.\n", fav_num);

    fav_num = get_fav_num(&state);
    printf("4) Current favourite number is %d.\n", fav_num);

    return 0;
}

अस्वीकरण: इस कोड को C99 या बाद के संस्करण की आवश्यकता है।

हालांकि यहां कोड एक साथ है, struct State {...}; और static inline फ़ंक्शन आमतौर पर एक हेडर .h फ़ाइल में जाएंगे।

साथ ही, मैं आपके get_state फ़ंक्शन को इस प्रकार सुधारूंगा:

enum Properties {
    FAV_NUM_MONDAY,
    FAV_NUM_NOT_MONDAY,
    IS_MONDAY,
    FAV_NUM
};

int get_state(const struct State *state, int property)
{

    switch (property) {
    case FAV_NUM_MONDAY:
        return  state->fav_num_monday;
    case FAV_NUM_NOT_MONDAY:
        return  state->fav_num_not_monday;
    case IS_MONDAY:
        return  state->is_monday;
    case FAV_NUM:
        return  get_fav_num(state);
    default:
        return -1;  /* Error */
    }
}

यह फ़ंक्शन एक सामान्य extern फ़ंक्शन होगा और एक .c फ़ाइल में जाएगा, हालांकि enum Properties को हेडर फ़ाइल में जाना चाहिए ताकि इसे फ़ंक्शन के उपयोगकर्ता द्वारा उपयोग किया जा सके।

संपादित करें: सरणी का उपयोग करके उच्च प्रदर्शन संस्करण जोड़ें

state.h

#include <stdint.h>

enum    State_Properties {
    FAV_NUM_MONDAY,
    FAV_NUM_NOT_MONDAY,
    IS_MONDAY,
    STATE_PROPERTIES
};


static inline
uint_fast8_t get_fav_num(const uint_fast8_t *restrict (state[STATE_PROPERTIES]))
{

    if ((*state)[IS_MONDAY])
        return  (*state)[FAV_NUM_MONDAY];
    else
        return  (*state)[FAV_NUM_NOT_MONDAY];
}

main.c

#include <inttypes.h>

#include "state.h"

int main(void)
{
    uint_fast8_t    state[STATE_PROPERTIES];
    uint_fast8_t    fav_num;
    uint_fast8_t    fav_num_monday;

    state   = (uint_fast8_t [STATE_PROPERTIES]){
        [FAV_NUM_MONDAY]        = 12;
        [FAV_NUM_NOT_MONDAY]    = 5;
        [IS_MONDAY]             = true;
    };

    // Print favourite number in different ways.
    fav_num = get_fav_num(&state);
    printf("5) Current favourite number is %"PRIuFAST8".\n", fav_num);

    // Example of how to retrieve any property:
    fav_num_monday  = state[FAV_NUM_MONDAY];
}

बेशक आप किसी को भी टाइप बदल सकते हैं जिसे आप चाहते हैं। मैंने uint_fast8_t का उपयोग किया, क्योंकि आपका डेटा वहां फिट हो सकता है, और यह किसी भी सिस्टम पर सबसे तेज़ प्रकार है।

2
alx 5 मार्च 2019, 15:31