2017-10-28 90 views
0
#include <cstdint> 
#include <cstring> 

template<typename T> 
T oph_(const char *s){ 
    constexpr std::size_t MAX = sizeof(T); 
    const  std::size_t size = strnlen(s, MAX); 

    T r = 0; 

    for(auto it = s; it - s < size; ++it) 
     r = r << 8 | *it; 

    return r; 
} 

inline uint64_t oph(const char *s){ 
    return oph_<uint64_t>(s); 
} 

int main(){ 
    uint64_t const a = oph("New York City"); 
    uint64_t const b = oph("Boston International"); 
    return a > b; 
} 

我想前8個字符轉換從const char *uint64_t這樣我就可以輕鬆地比較兩個字符串是否大於/較少。轉換小串的有效實施,uint64_t中

我知道等於半工作。

但是我不確定這是否是最有效的實現。

我希望這個實現可以在小型和大型機器上運行。

+0

我會更擔心'strnlen'在你的代碼。如果您正在進行順序搜索,則可以將數據複製爲每個字節的循環字節。 只需在BE機器上使用特定於cpu的指令交換字節。這應該是最快的方法。如果不需要查找字符串長度,則可以嘗試做更多。 – Ivan

+0

'strlen'是高度優化的,我不會擔心它,但我認爲你是對的 – Nick

回答

0

這是一個C實現,這應該是更快您的實現,但我仍然需要使用strncpy這應該是瓶頸

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

union small_str { 
    uint64_t v; 
    char buf[8]; 
}; 

static uint64_t fill_small_str(const char *str) 
{ 
    union small_str ss = { 0 }; 

    strncpy(ss.buf, str, 8); 
#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) 
    return ss.v; 
#else 
    return bswap_64(ss.v); 
#endif 
} 

int main(void) 
{ 
    uint64_t const a = fill_small_str("Aew York City"); 
    uint64_t const b = fill_small_str("Boston International"); 
    printf("%lu ; %lu ; %d\n", a, b, (a < b)); 
    return 0; 
} 
+0

愛你的實現 – Nick

+1

@Nick一個關於大端檢測的大警告,這些宏是一個gcc特有的功能。但實際上大部分的CPU都是小端。 – benjarobin

+0

在我的項目中,我已經使用endian.h,所以我使用'htobe64'。 – Nick