सबसे तेज तरीका एक स्ट्रिंग में पहले चार को हटाने के लिए


207

कहें कि हमारे पास निम्नलिखित स्ट्रिंग हैं

string data= "/temp string";

यदि हम पहले चरित्र को हटाना चाहते हैं तो हम /कई तरीकों से कर सकते हैं जैसे:

data.Remove(0,1);
data.TrimStart('/');
data.Substring(1);

लेकिन, वास्तव में मुझे नहीं पता कि कौन सा सबसे अच्छा एल्गोरिथ्म है और जो तेजी से कर रहा है ..
क्या कोई ऐसा है जो सबसे अच्छा है या सभी एक समान हैं?


क्या आप वैसे भी पहले चरित्र को हटाना चाहते हैं या आपको यह जाँचने की आवश्यकता है कि यह चरित्र वास्तव में है /?
SRKX

5
TrimStartपहले चार को दूर नहीं करेंगे, यह nशुरुआत से ही चार्ट को हटा देगा । Substringसबसे तेज है।
जारोस्लाव जंडेक

मुझे बस किसी भी पहले चरित्र को दूर करने की आवश्यकता है
अमृत ​​बडवी

6
यदि आप कोई पहला वर्ण हटा रहे हैं, TrimStart()तो पूरी तरह से प्रश्न से बाहर है।
BoltClock

@ बॉलकॉक: हाँ, यह वही है जो मैंने कहा था (टाइप किया हुआ)।
जारोस्लाव जंडेक

जवाबों:


147

दूसरा विकल्प वास्तव में दूसरों के समान नहीं है - यदि स्ट्रिंग "/// फू" है तो यह "// फू" के बजाय "फू" बन जाएगा।

पहले विकल्प को तीसरे की तुलना में समझने के लिए थोड़ा और काम करने की आवश्यकता है - मैं Substringविकल्प को सबसे सामान्य और पठनीय के रूप में देखूंगा।

(स्पष्ट रूप से उनमें से प्रत्येक एक अलग-अलग कथन के रूप में उपयोगी कुछ भी नहीं करेगा - आपको परिणाम को संभवतः एक चर के लिए आवंटित करने की आवश्यकता होगी data।)

जब तक यह वास्तव में आपके लिए एक समस्या न बन जाए - मैं इस बात पर ध्यान नहीं देता कि किस मामले में आपको पता होगा कि आपके पास परीक्षण के मामले हैं, और फिर प्रत्येक विकल्प के लिए उन परीक्षा मामलों को चलाना आसान है। परिणामों की तुलना करें। मैं Substringशायद यहाँ सबसे तेज़ होने की उम्मीद कर रहा हूँ , बस इसलिए कि Substringहमेशा मूल इनपुट के सिंगल चंक से एक स्ट्रिंग बनाते हैं, जबकि Removeकम से कम संभावित रूप से एक साथ एक स्टार्ट चंक और एक एंड चंक को गोंद करना होता है।


36
अब मैं प्रत्येक को 90000000 के बारे में कॉल करके चेक करता हूं और मैं निम्नलिखित परिणाम प्राप्त करता हूं: निकालें: 06.63 - ट्रिमस्टार्ट: 04.71 - सबस्ट्रिंग: 03.09 इसलिए परिणाम प्रतिस्थापन से सबसे अच्छा है
अम्र बदावी

5
बस याद रखें कि जब आप इस तरह से प्रदर्शन का परीक्षण कर रहे होते हैं, तो आप सीपीयू कैशिंग से प्रभावित होते हैं, इसलिए आपको यादृच्छिक स्ट्रिंग्स पर यह करने की आवश्यकता होती है, कि आपने किसी सरणी (सूची) को पहले से आबाद कर दिया है, और यादृच्छिक रूप से उस सरणी के तत्व का चयन करें ( सूची)।
19

12

मुझे पता है कि यह हाइपर-ऑप्टिमाइज़ेशन भूमि है, लेकिन ऐसा लग रहा था कि यह एक अच्छा बहाना है BenchmarkDotNet। इस परीक्षण का परिणाम (.NET कोर सम पर) है , जो इस नमूने के परीक्षण की Substringतुलना में कभी थोड़ा अधिक तेज है Remove: 19.37ns बनाम 22.52ns Remove। तो कुछ ~ 16% तेजी से।

using System;
using BenchmarkDotNet.Attributes;

namespace BenchmarkFun
{
    public class StringSubstringVsRemove
    {
        public readonly string SampleString = " My name is Daffy Duck.";

        [Benchmark]
        public string StringSubstring() => SampleString.Substring(1);

        [Benchmark]
        public string StringRemove() => SampleString.Remove(0, 1);

        public void AssertTestIsValid()
        {
            string subsRes = StringSubstring();
            string remvRes = StringRemove();

            if (subsRes == null
                || subsRes.Length != SampleString.Length - 1
                || subsRes != remvRes) {
                throw new Exception("INVALID TEST!");
            }
        }
    }

    class Program
    {
        static void Main()
        {
            // let's make sure test results are really equal / valid
            new StringSubstringVsRemove().AssertTestIsValid();

            var summary = BenchmarkRunner.Run<StringSubstringVsRemove>();
        }
    }
}

परिणाम:

BenchmarkDotNet=v0.11.4, OS=Windows 10.0.17763.253 (1809/October2018Update/Redstone5)
Intel Core i7-6700HQ CPU 2.60GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.0.100-preview-010184
  [Host]     : .NET Core 3.0.0-preview-27324-5 (CoreCLR 4.6.27322.0, CoreFX 4.7.19.7311), 64bit RyuJIT
  DefaultJob : .NET Core 3.0.0-preview-27324-5 (CoreCLR 4.6.27322.0, CoreFX 4.7.19.7311), 64bit RyuJIT

|          Method |     Mean |     Error |    StdDev |
|---------------- |---------:|----------:|----------:|
| StringSubstring | 19.37 ns | 0.3940 ns | 0.3493 ns |
|    StringRemove | 22.52 ns | 0.4062 ns | 0.3601 ns |

9

मुझे लगता है कि लगता है कि चाहते हैं Removeऔर Substringपहले स्थान के लिए तार का एक निश्चित-आकार हिस्से को दोनों slurp टाई होता है, क्योंकि वे है, जबकि TrimStartप्रत्येक चरित्र पर एक परीक्षण के साथ छोड़ दिया से एक स्कैन करता है और उसके बाद के रूप में बिल्कुल वैसा ही काम करने के लिए है अन्य दो तरीके। गंभीरता से, हालांकि, यह बालों को विभाजित कर रहा है।


1
वास्तव में, Substringकी तुलना में तेज है Remove, क्योंकि Removeकॉल Substring
जारोस्लाव जंडेक

@ जारोस्लाव: यह सच नहीं है। दोनों Substringऔर Remove, एक निजी विधि पर भरोसा करते हैं FillSubstring
मार्सेलो कैंटोस

यह सत्यापित नहीं किया है, लेकिन यह बहुत अच्छा लगता है:string Remove(this string source, int from, int to) { return source.SubString(0, from) + source.SubString(to); }
Dykam

1
@ जारॉस्लाव: मैं काफी पारंपरिक विंडोज देव वातावरण पर mscorlib.dll में दो तरीकों के परावर्तक डिससेप्शन को घूर रहा हूं। वे दोनों System.PInvoke.EE.AllocateStringगंतव्य स्ट्रिंग ऑब्जेक्ट को आवंटित करने के लिए कॉल करते हैं और फिर FillSubstringवर्णों को कॉपी करने के लिए कॉल करते हैं। क्या मैं गलत चीज़ देख रहा हूँ?
मार्सेलो कैंटोस

1
@ मार्सेलो: वैसे भी, आपकी पहली टिप्पणी ने मूल रूप से एक अलग बात कही थी। मुझे शायद एक बेहतर शब्द का उपयोग करना चाहिए था, हालांकि यह बिंदु वैध है ( Substring> Remove)। मैं आगे टिप्पणी नहीं करने जा रहा क्योंकि चर्चा में मेरा काफी समय लगा।
जारोस्लाव जंडेक

6

यदि आप वास्तव में परवाह करते हैं, तो आप इसे प्रोफाइल कर सकते हैं। कई पुनरावृत्तियों का एक लूप लिखें और देखें कि क्या होता है। हालांकि, संभावना है कि यह आपके आवेदन में अड़चन नहीं है, और ट्रिमस्टार्ट सबसे शब्दार्थ रूप से सही लगता है। अनुकूलन करने से पहले कोड को आसानी से लिखने का प्रयास करें।


6
TrimStartकम से कम सही है, क्योंकि सिर्फ पहले "//temp string".TrimStart('/')को नहीं हटाएगा '/'
मार्सेलो कैंटोस

फ़ंक्शन को तब खराब नाम दिया गया है। मैं सी # आदमी नहीं हूं।
स्टीफन केंडल

@StefanKendall: टैग देखें
विजय सिंह राणा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.