Metode mana yang terbaik (lebih idomatik) untuk menguji string yang tidak kosong (dalam Go)?
if len(mystring) > 0 { }
Atau:
if mystring != "" { }
Atau sesuatu yang lain?
Kedua gaya digunakan dalam perpustakaan standar Go.
if len(s) > 0 { ... }
dapat ditemukan dalam strconv
paket: http://golang.org/src/pkg/strconv/atoi.go
if s != "" { ... }
dapat ditemukan dalam encoding/json
paket: http://golang.org/src/pkg/encoding/json/encode.go
Keduanya idiomatis dan cukup jelas. Ini lebih merupakan masalah selera pribadi dan tentang kejelasan.
Russ Cox menulis di utas kacang kacangan :
Yang membuat kodenya jelas.
Jika saya akan melihat elemen x saya biasanya menulis
len (s)> x, bahkan untuk x == 0, tetapi jika saya peduli
"apakah ini string spesifik ini" Saya cenderung menulis s == "".Masuk akal untuk mengasumsikan bahwa kompiler matang akan mengkompilasi
len (s) == 0 dan s == "" ke dalam kode yang sama dan efisien.
...Buat kode menjadi jelas.
Seperti yang ditunjukkan dalam jawaban Timmmm , kompiler Go memang menghasilkan kode yang identik dalam kedua kasus.
if mystring != "" { }
adalah cara terbaik, disukai dan idiomatik HARI INI. Alasan pustaka standar berisi sebaliknya adalah karena itu ditulis sebelum 2010 ketikalen(mystring) == 0
optimasi masuk akal.len
untuk memeriksa string kosong / tidak kosong. Seperti ini yang dilakukan oleh Brad Fitzpatrick. Saya khawatir ini masih soal selera dan kejelasan;)len(v) > 0
pada h2_bundle.go (baris 2702). Itu tidak ditampilkan secara otomatis karena dihasilkan dari golang.org/x/net/http2, saya percaya.Ini tampaknya merupakan optimasi mikro prematur. Kompiler bebas untuk menghasilkan kode yang sama untuk kedua kasus atau setidaknya untuk keduanya
dan
karena semantiknya jelas sama.
sumber
Memeriksa panjang adalah jawaban yang baik, tetapi Anda juga bisa menjelaskan string "kosong" yang juga hanya spasi kosong. Bukan "secara teknis" kosong, tetapi jika Anda ingin memeriksa:
sumber
TrimSpace
akan mengalokasikan dan menyalin string baru dari string asli, sehingga pendekatan ini akan memperkenalkan inefisiensi pada skala.s
adalah tipe string,s[0:i]
mengembalikan salinan baru. String tidak dapat diubah di Go, jadi apakah itu perlu membuat salinan di sini?strings.TrimSpace( s )
tidak akan menyebabkan alokasi string baru dan karakter copy jika string tidak perlu pemangkasan, tetapi jika string memang perlu pemangkasan maka salinan tambahan (tanpa karakter spasi) akan dipanggil.gocritic
linter menyarankan menggunakanstrings.TrimSpace(str) == ""
bukannya cek panjang.Dengan asumsi bahwa ruang kosong dan semua spasi putih depan dan belakang harus dihilangkan:
Karena:
len("") // is 0
len(" ") // one empty space is 1
len(" ") // two empty spaces is 2
sumber
< 1
+1Sampai sekarang, kompiler Go menghasilkan kode identik dalam kedua kasus, jadi ini adalah masalah selera. GCCGo memang menghasilkan kode yang berbeda, tetapi nyaris tidak ada yang menggunakannya jadi saya tidak akan khawatir tentang itu.
https://godbolt.org/z/fib1x1
sumber
Akan lebih bersih dan lebih rentan kesalahan untuk menggunakan fungsi seperti di bawah ini:
sumber
Hanya untuk menambahkan komentar
Terutama tentang bagaimana melakukan pengujian kinerja.
Saya melakukan pengujian dengan kode berikut:
Dan hasilnya adalah:
Varian yang efektif biasanya tidak mencapai waktu tercepat dan hanya ada perbedaan minimal (sekitar 0,01ns / op) antara varian top speed.
Dan jika saya melihat log lengkap, perbedaan antara percobaan lebih besar daripada perbedaan antara fungsi benchmark.
Juga sepertinya tidak ada perbedaan yang terukur antara BenchmarkStringCheckEq dan BenchmarkStringCheckNe atau BenchmarkStringCheckLen dan BenchmarkStringCheckLenGt bahkan jika varian terakhir harus termasuk 6 kali, bukannya 2 kali.
Anda dapat mencoba untuk mendapatkan kepercayaan diri tentang kinerja yang sama dengan menambahkan tes dengan tes yang dimodifikasi atau loop dalam. Ini lebih cepat:
Ini tidak lebih cepat:
Kedua varian biasanya lebih cepat atau lebih lambat daripada perbedaan antara tes utama.
Ini juga baik untuk menghasilkan string uji (ss) menggunakan generator string dengan distribusi yang relevan. Dan memiliki panjang variabel juga.
Jadi saya tidak memiliki keyakinan perbedaan kinerja antara metode utama untuk menguji string kosong.
Dan saya dapat menyatakan dengan percaya diri, lebih cepat untuk tidak menguji string kosong sama sekali daripada menguji string kosong. Dan juga lebih cepat untuk menguji string kosong daripada menguji 1 string char (varian awalan).
sumber
Sesuai pedoman resmi dan dari sudut pandang kinerja mereka tampak setara ( jawaban ANisus ), s! = "" Akan lebih baik karena keuntungan sintaksis. s! = "" akan gagal pada waktu kompilasi jika variabelnya bukan string, sementara len (s) == 0 akan lulus untuk beberapa tipe data lainnya.
sumber
len()
hanya membutuhkan sedikit kerja ekstra. NAMUN, satu hal yang biasa kita lakukan di C adalah melemparkan sisi kiri ke aconst
atau meletakkan string statis di sisi kiri operator untuk mencegah s == "" dari menjadi s = "" yang dalam sintaks C dapat diterima. .. dan mungkin golang juga. (lihat diperpanjang jika)Ini akan lebih berkinerja daripada memangkas seluruh string, karena Anda hanya perlu memeriksa setidaknya satu karakter non-spasi yang ada
sumber
Saya pikir cara terbaik adalah membandingkan dengan string kosong
BenchmarkStringCheck1 memeriksa dengan string kosong
BenchmarkStringCheck2 memeriksa dengan len nol
Saya memeriksa dengan memeriksa string kosong dan tidak kosong. Anda dapat melihat bahwa memeriksa dengan string kosong lebih cepat.
Kode
sumber