Skip to content

搞英语 → 看世界

翻译英文优质信息和名人推特

Menu
  • 首页
  • 作者列表
  • 独立博客
  • 专业媒体
  • 名人推特
  • 邮件列表
  • 关于本站
Menu

快速检查一个字符串是否属于一个小集合

Posted on 2022-12-30

肖像2018facebook.jpg

假设我给你一组参考字符串(“ftp”、“file”、“http”、“https”、“ws”、“wss”)。给定一个新字符串,您想快速判断它是否是该集合的一部分。

一个明智的解决方案可能是创建一个集合,然后询问字符串是否在集合中。在 C++ 中,默认的集合类型是 unordered_set 因此您的代码可能如下所示:

 static const std :: unordered_set < std :: string_view > special_set = {  
   
    “ ftp ” 、 “文件” 、 “ http ” 、 “ https ” 、 “ ws ” 、 “ wss ” } ;  
   
  
   
bool hash_is_special ( std :: string_view 输入) {  
   
  返回special_set 。查找(输入) ! = special_set 。结束( ) ;  
   
}  
   

你也可以更直接一点,做几个​​比较就可以了:

 bool direct_is_special ( std :: string_view 输入) {  
   
  返回(输入== “ https ” ) | (输入== “ http ” ) | (输入== “ ftp ” ) |  
   
         (输入== “文件” ) | (输入== “ ws ” ) | (输入== “ wss ” ) ;  
   
}  
   

如果您查看代码的编译方式,您可能会注意到编译器被迫进行比较和跳转,因为它不允许读取超出其报告大小的提供的字符串。

如果您可以告诉您的编译器您收到的字符串是“填充的”以便您可以从中安全地读取八个字节,那么您可能会做得更好。我找不到一种非常优雅的方法来做到这一点,但以下代码有效:

静态内联uint64_t string_to_uint64 ( std :: string_view view ) {  
   
  uint64_t 值;  
   
  std :: memcpy ( & val , view.data ( ) , sizeof ( uint64_t ) ) ;  
   
  返回值;  
   
}  
   
  
   
uint32_t string_to_uint32 ( const char * data ) {  
   
  uint32_t 值;  
   
  std :: memcpy ( & val ,数据, sizeof ( uint32_t ) ) ;  
   
  返回值;  
   
}  
   
  
   
  
   
bool fast_is_special ( std :: string_view 输入) {  
   
  uint64_t inputu = string_to_uint64 (输入) ;  
   
  如果( ( inputu & 0xffffffffff ) = = string_to_uint64 ( " https \0 \0 \0 " ) ) {  
   
    返回输入。尺寸( ) = = 5 ;  
   
  }  
   
  如果( ( inputu & 0xffffffff ) = = string_to_uint64 ( " http \0 \0 \0 \0 " ) ) {  
   
    返回输入。尺寸( ) = = 4 ;  
   
  }  
   
  如果( uint32_t ( inputu ) == string_to_uint32 ( “文件” ) ) {  
   
    返回输入。尺寸( ) = = 4 ;  
   
  }  
   
  如果( ( inputu & 0xffffff ) = = string_to_uint32 ( " ftp \0 " ) ) {  
   
    返回输入。尺寸( ) = = 3 ;  
   
  }  
   
  如果( ( inputu & 0xffffff ) = = string_to_uint32 ( " wss \0 " ) ) {  
   
    返回输入。尺寸( ) = = 3 ;  
   
  }  
   
  如果( ( inputu & 0xffff ) = = string_to_uint32 ( " ws \0 \0 " ) ) {  
   
    返回输入。尺寸( ) = = 2 ;  
   
  }  
   
  返回假;  
   
}  
   

虽然我没有这样做,但您可以扩展比较,使其不区分大小写(只需将输入与字节 0xdf 而不是字节 0xff 进行 AND 运算)。

我相信有更快更聪明的选择!

无论如何,我的选择有多快?在 Intel Ice Lake 服务器上使用 GCC 11,我得到以下结果:

std::unordered_map 20 纳秒/串
直接的 9.1 纳秒/串
快速地 3.0 纳秒/串

在带有 LLVM 12 的 Apple M2 上,我得到了类似(但更好)的结果:

std::unordered_map 14 纳秒/串
直接的 5.5 纳秒/串
快速地 1.6 纳秒/串

优化此类小函数时需要小心:函数是否内联以及如何内联对于良好的性能至关重要。

我的源代码可用。

原文: https://lemire.me/blog/2022/12/30/quickly-checking-that-a-string-belongs-to-a-small-set/

本站文章系自动翻译,站长会周期检查,如果有不当内容,请点此留言,非常感谢。
  • Abhinav
  • Abigail Pain
  • Adam Fortuna
  • Alberto Gallego
  • Alex Wlchan
  • Answer.AI
  • Arne Bahlo
  • Ben Carlson
  • Ben Kuhn
  • Bert Hubert
  • Bits about Money
  • Brian Krebs
  • ByteByteGo
  • Chip Huyen
  • Chips and Cheese
  • Christopher Butler
  • Colin Percival
  • Cool Infographics
  • Dan Sinker
  • David Walsh
  • Dmitry Dolzhenko
  • Dustin Curtis
  • Elad Gil
  • Ellie Huxtable
  • Ethan Marcotte
  • Exponential View
  • FAIL Blog
  • Founder Weekly
  • Geoffrey Huntley
  • Geoffrey Litt
  • Greg Mankiw
  • Henrique Dias
  • Hypercritical
  • IEEE Spectrum
  • Investment Talk
  • Jaz
  • Jeff Geerling
  • Jonas Hietala
  • Josh Comeau
  • Lenny Rachitsky
  • Liz Danzico
  • Lou Plummer
  • Luke Wroblewski
  • Matt Baer
  • Matt Stoller
  • Matthias Endler
  • Mert Bulan
  • Mostly metrics
  • News Letter
  • NextDraft
  • Non_Interactive
  • Not Boring
  • One Useful Thing
  • Phil Eaton
  • Product Market Fit
  • Readwise
  • ReedyBear
  • Robert Heaton
  • Ruben Schade
  • Sage Economics
  • Sam Altman
  • Sam Rose
  • selfh.st
  • Shtetl-Optimized
  • Simon schreibt
  • Slashdot
  • Small Good Things
  • Taylor Troesh
  • Telegram Blog
  • The Macro Compass
  • The Pomp Letter
  • thesephist
  • Thinking Deep & Wide
  • Tim Kellogg
  • Understanding AI
  • 英文媒体
  • 英文推特
  • 英文独立博客
©2025 搞英语 → 看世界 | Design: Newspaperly WordPress Theme