উত্তর:
উভয় স্টাইল গো স্ট্যান্ডার্ড লাইব্রেরিতে ব্যবহার করা হয়।
if len(s) > 0 { ... }
strconv
প্যাকেজে পাওয়া যাবে : http://golang.org/src/pkg/strconv/atoi.go
if s != "" { ... }
encoding/json
প্যাকেজে পাওয়া যাবে : http://golang.org/src/pkg/encoding/json/encode.go
উভয়ই মূর্খবাদী এবং যথেষ্ট পরিষ্কার। এটি ব্যক্তিগত স্বাদ এবং স্পষ্টতা সম্পর্কিত বিষয়।
রাশ কক্স একটি গোলং-বাদামের থ্রেডে লিখেছেন :
কোডটি পরিষ্কার করে তোলে one
যদি আমি এক্স উপাদানটি দেখতে যাচ্ছি তবে আমি সাধারণত
লেন (গুলি)> x লিখি এমনকি x == 0 এর জন্যও লিখি তবে আমি যদি "যত্নশীল
" তবে এই নির্দিষ্ট স্ট্রিংটি "আমি s ==" "লেখার ঝোঁক রাখি।"এটি ধরে নেওয়া যুক্তিযুক্ত যে একটি পরিপক্ক সংকলক
লেন (গুলি) == 0 এবং s == "" একই, কার্যকর কোডে সংকলন করবে ।
...কোডটি পরিষ্কার করুন।
টিএমএমএম এর উত্তরে নির্দেশিত হিসাবে , গো সংকলক উভয় ক্ষেত্রে অভিন্ন কোড তৈরি করে।
len
খালি / খালি খালি স্ট্রিংগুলি পরীক্ষা করে 1 বছরের কম বয়সী স্ট্যান্ডার্ড লাইব্রেরিতে কমিটস পাওয়া গেছে । ব্র্যাড ফিটজপ্যাট্রিকের এই প্রতিশ্রুতি পছন্দ করুন । আমি আশঙ্কা করছি এটি এখনও স্বাদ এবং স্পষ্টতার বিষয়;)
len(v) > 0
এ উল্লেখ করছি । এটি golang.org/x/net/http2 থেকে উত্পন্ন হওয়ায় এটি স্বয়ংক্রিয়ভাবে প্রদর্শিত হয় না, আমি বিশ্বাস করি।
এটি অকাল মাইক্রোপটিমাইজেশন বলে মনে হচ্ছে। সংকলক উভয় ক্ষেত্রে বা কমপক্ষে এই দুটিয়ের জন্য একই কোড তৈরি করতে বিনামূল্যে
if len(s) != 0 { ... }
এবং
if s != "" { ... }
কারণ শব্দার্থবিজ্ঞান স্পষ্টভাবে সমান।
দৈর্ঘ্যের জন্য পরীক্ষা করা ভাল উত্তর, তবে আপনি "খালি" স্ট্রিংয়ের জন্যও অ্যাকাউন্ট করতে পারেন যা কেবল শ্বেত স্পেস। "প্রযুক্তিগতভাবে" খালি নয়, তবে যদি আপনি এটি পরীক্ষা করে দেখেন:
package main
import (
"fmt"
"strings"
)
func main() {
stringOne := "merpflakes"
stringTwo := " "
stringThree := ""
if len(strings.TrimSpace(stringOne)) == 0 {
fmt.Println("String is empty!")
}
if len(strings.TrimSpace(stringTwo)) == 0 {
fmt.Println("String two is empty!")
}
if len(stringTwo) == 0 {
fmt.Println("String two is still empty!")
}
if len(strings.TrimSpace(stringThree)) == 0 {
fmt.Println("String three is empty!")
}
}
TrimSpace
মূল স্ট্রিং থেকে একটি নতুন স্ট্রিং বরাদ্দ এবং অনুলিপি করবে, সুতরাং এই পদ্ধতির স্কেল অদক্ষতা প্রবর্তন করবে।
s
টাইপ স্ট্রিংয়ের সাথে s[0:i]
একটি নতুন অনুলিপি প্রদান করে। স্ট্রিংগুলি গোতে পরিবর্তনযোগ্য, তাই এখানে কি একটি অনুলিপি তৈরি করা দরকার?
strings.TrimSpace( s )
স্ট্রিংটি ছাঁটাইয়ের প্রয়োজন না হলে নতুন স্ট্রিং বরাদ্দ এবং চরিত্রের অনুলিপি তৈরি করবে না, তবে যদি স্ট্রিংটি ছাঁটাইয়ের প্রয়োজন হয় তবে অতিরিক্ত অনুলিপি (হোয়াইটস্পেস অক্ষর ছাড়াই) ডাকা হবে।
gocritic
Linter ব্যবহার প্রস্তাব দেওয়া strings.TrimSpace(str) == ""
দৈর্ঘ্য চেকের পরিবর্তে।
ধরে নিচ্ছি যে খালি জায়গা এবং সমস্ত নেতৃস্থানীয় এবং অনুসরণকারী শ্বেত স্থানগুলি সরানো উচিত:
import "strings"
if len(strings.TrimSpace(s)) == 0 { ... }
কারণ :
len("") // is 0
len(" ") // one empty space is 1
len(" ") // two empty spaces is 2
< 1
+1 করা
এখন পর্যন্ত, গো সংকলক উভয় ক্ষেত্রে অভিন্ন কোড উত্পন্ন করে, তাই এটি স্বাদের বিষয়। জিসিসিগো বিভিন্ন কোড উত্পন্ন করে তবে খুব কমই কেউ এটিকে ব্যবহার করে তাই আমি সে সম্পর্কে চিন্তা করব না।
এটি নীচের মত একটি ফাংশন ব্যবহার করা পরিষ্কার এবং কম ত্রুটিযুক্ত হবে:
func empty(s string) bool {
return len(strings.TrimSpace(s)) == 0
}
মূলত পারফরম্যান্স টেস্টিং কীভাবে করা যায় about
আমি নিম্নলিখিত কোড দিয়ে পরীক্ষা করেছি:
import (
"testing"
)
var ss = []string{"Hello", "", "bar", " ", "baz", "ewrqlosakdjhf12934c r39yfashk fjkashkfashds fsdakjh-", "", "123"}
func BenchmarkStringCheckEq(b *testing.B) {
c := 0
b.ResetTimer()
for n := 0; n < b.N; n++ {
for _, s := range ss {
if s == "" {
c++
}
}
}
t := 2 * b.N
if c != t {
b.Fatalf("did not catch empty strings: %d != %d", c, t)
}
}
func BenchmarkStringCheckLen(b *testing.B) {
c := 0
b.ResetTimer()
for n := 0; n < b.N; n++ {
for _, s := range ss {
if len(s) == 0 {
c++
}
}
}
t := 2 * b.N
if c != t {
b.Fatalf("did not catch empty strings: %d != %d", c, t)
}
}
func BenchmarkStringCheckLenGt(b *testing.B) {
c := 0
b.ResetTimer()
for n := 0; n < b.N; n++ {
for _, s := range ss {
if len(s) > 0 {
c++
}
}
}
t := 6 * b.N
if c != t {
b.Fatalf("did not catch empty strings: %d != %d", c, t)
}
}
func BenchmarkStringCheckNe(b *testing.B) {
c := 0
b.ResetTimer()
for n := 0; n < b.N; n++ {
for _, s := range ss {
if s != "" {
c++
}
}
}
t := 6 * b.N
if c != t {
b.Fatalf("did not catch empty strings: %d != %d", c, t)
}
}
এবং ফলাফলগুলি ছিল:
% for a in $(seq 50);do go test -run=^$ -bench=. --benchtime=1s ./...|grep Bench;done | tee -a log
% sort -k 3n log | head -10
BenchmarkStringCheckEq-4 150149937 8.06 ns/op
BenchmarkStringCheckLenGt-4 147926752 8.06 ns/op
BenchmarkStringCheckLenGt-4 148045771 8.06 ns/op
BenchmarkStringCheckNe-4 145506912 8.06 ns/op
BenchmarkStringCheckLen-4 145942450 8.07 ns/op
BenchmarkStringCheckEq-4 146990384 8.08 ns/op
BenchmarkStringCheckLenGt-4 149351529 8.08 ns/op
BenchmarkStringCheckNe-4 148212032 8.08 ns/op
BenchmarkStringCheckEq-4 145122193 8.09 ns/op
BenchmarkStringCheckEq-4 146277885 8.09 ns/op
কার্যকরভাবে ভেরিয়েন্টগুলি দ্রুততম সময়ে পৌঁছায় না এবং বৈকল্পিক শীর্ষ গতির মধ্যে কেবলমাত্র ন্যূনতম পার্থক্য (প্রায় 0.01ns / op) থাকে।
এবং আমি যদি সম্পূর্ণ লগ দেখতে পাই তবে চেষ্টাগুলির মধ্যে পার্থক্যটি বেঞ্চমার্ক ফাংশনগুলির মধ্যে পার্থক্যের চেয়ে বেশি।
এছাড়াও বেঞ্চমার্কস্ট্রিংচেকএক এবং বেঞ্চমার্কস্ট্রিংচেকনি বা বেনমার্কস্ট্রিংচেকলেন এবং বেঞ্চমার্কস্ট্রিংচেকলেনগেটের মধ্যে কোনও পরিমাপযোগ্য পার্থক্য রয়েছে বলে মনে হয় না যদিও ল্যাটার্ট ভেরিয়েন্টগুলি 2 বারের পরিবর্তে 6 বার inc করা উচিত।
আপনি পরিবর্তিত পরীক্ষা বা অভ্যন্তরীণ লুপ দিয়ে পরীক্ষা যোগ করে সমান পারফরম্যান্স সম্পর্কে কিছুটা আস্থা অর্জনের চেষ্টা করতে পারেন get এটি দ্রুত:
func BenchmarkStringCheckNone4(b *testing.B) {
c := 0
b.ResetTimer()
for n := 0; n < b.N; n++ {
for _, _ = range ss {
c++
}
}
t := len(ss) * b.N
if c != t {
b.Fatalf("did not catch empty strings: %d != %d", c, t)
}
}
এটি দ্রুত নয়:
func BenchmarkStringCheckEq3(b *testing.B) {
ss2 := make([]string, len(ss))
prefix := "a"
for i, _ := range ss {
ss2[i] = prefix + ss[i]
}
c := 0
b.ResetTimer()
for n := 0; n < b.N; n++ {
for _, s := range ss2 {
if s == prefix {
c++
}
}
}
t := 2 * b.N
if c != t {
b.Fatalf("did not catch empty strings: %d != %d", c, t)
}
}
উভয় রূপই প্রধান পরীক্ষার মধ্যে পার্থক্যের চেয়ে দ্রুত বা ধীর হয়।
প্রাসঙ্গিক বিতরণ সহ স্ট্রিং জেনারেটর ব্যবহার করে পরীক্ষার স্ট্রিং (গুলি) তৈরি করা ভাল। এবং পরিবর্তনশীল দৈর্ঘ্য আছে।
সুতরাং চলতে ফাঁকা স্ট্রিং পরীক্ষা করার জন্য প্রধান পদ্ধতির মধ্যে পারফরম্যান্স পার্থক্যের কোনও আত্মবিশ্বাস আমার নেই।
এবং আমি কিছুটা আত্মবিশ্বাসের সাথে বলতে পারি, খালি স্ট্রিংটি টেস্ট খালি স্ট্রিংয়ের চেয়ে খালি স্ট্রিংটি না পরীক্ষা করা দ্রুত। এবং 1 টি স্ট্রিং (উপসর্গের বৈকল্পিক) পরীক্ষা করার চেয়ে খালি স্ট্রিংটি পরীক্ষা করা আরও দ্রুত।
অফিসিয়াল গাইডলাইন অনুসারে এবং পারফরম্যান্সের দৃষ্টিকোণ থেকে এগুলি সমতুল্য উপস্থিত হয় ( এ্যানিসাস উত্তর ), সিন্টেক্সটিক্যাল সুবিধার কারণে s! = "" ভাল হবে। s! = "" সংকলনের সময় ব্যর্থ হবে যদি ভেরিয়েবলটি স্ট্রিং না হয় তবে লেন (গুলি) == 0 অন্যান্য কয়েকটি ডেটা ধরণের জন্য পাস করবে।
len()
কেবল সামান্য অতিরিক্ত অতিরিক্ত কাজ প্রয়োজন requires যাইহোক, আমরা সিতে যে জিনিসটি ব্যবহার করতাম সেটিকে বাম দিকটি একটিতে ফেলে দেওয়া হয়েছিল const
বা s == "" s = "" হওয়া থেকে রোধ করতে অপারেটরের বাম দিকে স্থিতিযুক্ত স্ট্রিং লাগানো ছিল যা সি বাক্য গঠনতে গ্রহণযোগ্য। .. এবং সম্ভবত গোলংও। (প্রসারিত যদি দেখুন)
পুরো স্ট্রিংটি ছাঁটাইয়ের চেয়ে এটি আরও পারফরম্যান্স হতে পারে, যেহেতু আপনাকে কেবল কমপক্ষে একটি অ-স্থান অক্ষর বিদ্যমান আছে তা পরীক্ষা করতে হবে
// Strempty checks whether string contains only whitespace or not
func Strempty(s string) bool {
if len(s) == 0 {
return true
}
r := []rune(s)
l := len(r)
for l > 0 {
l--
if !unicode.IsSpace(r[l]) {
return false
}
}
return true
}
আমি মনে করি সবচেয়ে ভাল উপায়টি ফাঁকা স্ট্রিংয়ের সাথে তুলনা করা
বেঞ্চমার্কস্ট্রিংচেক 1 ফাঁকা স্ট্রিং সহ চেক করছে
বেনমার্কস্ট্রিংচেক 2 লেন শূন্যের সাথে চেক করছে
আমি খালি এবং খালি খালি স্ট্রিং চেকিংয়ের সাথে চেক করি। আপনি দেখতে পাচ্ছেন যে একটি ফাঁকা স্ট্রিং দিয়ে চেক করা দ্রুত।
BenchmarkStringCheck1-4 2000000000 0.29 ns/op 0 B/op 0 allocs/op
BenchmarkStringCheck1-4 2000000000 0.30 ns/op 0 B/op 0 allocs/op
BenchmarkStringCheck2-4 2000000000 0.30 ns/op 0 B/op 0 allocs/op
BenchmarkStringCheck2-4 2000000000 0.31 ns/op 0 B/op 0 allocs/op
কোড
func BenchmarkStringCheck1(b *testing.B) {
s := "Hello"
b.ResetTimer()
for n := 0; n < b.N; n++ {
if s == "" {
}
}
}
func BenchmarkStringCheck2(b *testing.B) {
s := "Hello"
b.ResetTimer()
for n := 0; n < b.N; n++ {
if len(s) == 0 {
}
}
}
if mystring != "" { }
আজ, সেরা, পছন্দসই এবং প্রতিচ্ছবিযুক্ত উপায়। স্ট্যান্ডার্ড লাইব্রেরিতে অন্যথায় থাকার কারণটি এটি ২০১০ এর আগে লেখা হয়েছিল যখনlen(mystring) == 0
অপ্টিমাইজেশনের অর্থ হয়েছিল।