রুবিতে স্ট্রিং কনকনেটেশন


364

আমি রুবিতে আরও বেশি মার্জিত উপায়ের সন্ধান করছি।

আমার নিচের লাইনটি রয়েছে:

source = "#{ROOT_DIR}/" << project << "/App.config"

এটি করার একটি সুন্দর উপায় আছে?

এবং এই ক্ষেত্রে <<এবং মধ্যে পার্থক্য কি +?


3
এই প্রশ্নটি স্ট্যাকওভারফ্লো . com/ প্রশ্নগুলি / 6868 .৪৪464646/২ অত্যন্ত সম্পর্কিত।
চোখ

<< এটি সংক্ষিপ্তকরণ করার আরও কার্যকর উপায়।
তাইমুর চাংগাইজ

উত্তর:


574

আপনি এটি বিভিন্ন উপায়ে করতে পারেন:

  1. আপনি যেমনটি দেখিয়েছেন <<তবে এটি সাধারণ উপায় নয়
  2. স্ট্রিং বিরতি সহ

    source = "#{ROOT_DIR}/#{project}/App.config"
  3. সঙ্গে +

    source = "#{ROOT_DIR}/" + project + "/App.config"

দ্বিতীয় পদ্ধতিটি আমি যা দেখেছি তার থেকে স্মৃতি / গতির মেয়াদে আরও দক্ষ বলে মনে হচ্ছে (যদিও এটি মাপা হয়নি)। ROOT_DIR শূন্য হলে এই তিনটি পদ্ধতিই একটি অবিচ্ছিন্ন ধ্রুবক ত্রুটি ফেলবে।

পথের নামগুলি নিয়ে কাজ করার সময়, আপনি File.joinপথের নাম পৃথককারীকে নিয়ে ঝামেলা এড়াতে ব্যবহার করতে পারেন want

শেষ পর্যন্ত এটি স্বাদের বিষয়।


7
আমি রুবি নিয়ে খুব বেশি অভিজ্ঞ নই। তবে সাধারণত আপনি যখন স্ট্রিং প্রচুর পরিমাণে সংহত করেন আপনি প্রায়শই স্ট্রিংগুলিকে একটি অ্যারেতে সংযুক্ত করে এবং তারপরে শেষে স্ট্রিংটিকে পরমাণুর সাথে একত্রে রেখে পারফরম্যান্স অর্জন করতে পারেন। তাহলে << দরকারী হতে পারে?
পিইজেড

1
আপনাকে যেকোন উপায়ে এটির মধ্যে দীর্ঘতর স্ট্রিংয়ের একটি অনুলিপি মেমরি যুক্ত করতে হবে। << কমবেশি + এর সমান হয় তবে আপনি << একটি একক চরিত্রের সাথে করতে পারেন।
কেলটিয়া

9
<< অ্যারের উপাদানগুলিতে << ব্যবহারের পরিবর্তে অ্যারে # জোড় ব্যবহার করুন, এটি আরও দ্রুত।
গ্রান্ট হাচিন্স

94

+অপারেটর স্বাভাবিক সংযুক্তকরণের পছন্দ, এবং সম্ভবত CONCATENATE স্ট্রিং দ্রুততম উপায়।

+এবং এর মধ্যে পার্থক্যটি <<হ'ল <<তার বাম দিকে বস্তুটি পরিবর্তন করে, এবং +না।

irb(main):001:0> s = 'a'
=> "a"
irb(main):002:0> s + 'b'
=> "ab"
irb(main):003:0> s
=> "a"
irb(main):004:0> s << 'b'
=> "ab"
irb(main):005:0> s
=> "ab"

32
+ অপারেটর অবশ্যই স্ট্রিংগুলি সংযুক্ত করার দ্রুততম উপায় নয়। যতবারই আপনি এটি ব্যবহার করেন, এটি একটি অনুলিপি তৈরি করে whereas
এভিল ট্রাউট

5
বেশিরভাগ ব্যবহারের জন্য, সংক্ষেপণ +এবং <<প্রায় একই রকম হতে চলেছে। আপনি যদি অনেকগুলি স্ট্রিং, বা সত্যিই বড়গুলি নিয়ে কাজ করে থাকেন তবে আপনি একটি পার্থক্য লক্ষ্য করতে পারেন। তারা কীভাবে অনুরূপ অভিনয় করে আমি অবাক হয়েছিলাম। gist.github.com/2895311
ম্যাট বার্ক

8
আপনার জারুবি ফলাফলগুলি প্রারম্ভিক-চালিত জেভিএম ওভারলোডের দ্বারা বিরতিতে বিভক্ত হয়। যদি আপনি 5.times do ... endপ্রতিটি দোভাষীর জন্য পরীক্ষার স্যুটটি বেশ কয়েকবার চালিত করেন (একই প্রক্রিয়াতে - সুতরাং একটি ব্লক বলে সমস্ত কিছু মোড়ানো ), আপনি আরও সঠিক ফলাফল দিয়ে শেষ করতে পারেন। আমার পরীক্ষাটি দেখিয়েছে যে সমস্ত রুবি ইন্টারপ্রেটারে জুড়ে ইন্টারপোলেশনটি দ্রুততম পদ্ধতি। আমি <<দ্রুততম হওয়ার আশা করতাম , তবে সে কারণেই আমরা বেঞ্চমার্ক করব।
দুরন্ত

রুবির বিষয়ে খুব বেশি পারদর্শী না হয়ে, আমি আগ্রহী যে ম্যুটেশনটি স্তূপে সঞ্চালিত হয় বা স্তূপে হয় কিনা? যদি গাদা হয়, এমনকি একটি মিউটেশন অপারেশন, যা এটি দ্রুত হওয়া উচিত বলে মনে হয়, সম্ভবত মলোকের কোনও রূপ জড়িত। এটি না করে আমি একটি বাফার ওভারফ্লো আশা করতাম। স্ট্যাকটি ব্যবহার করা খুব দ্রুত হতে পারে তবে ফলস্বরূপ মানটি যেভাবেই হোক স্তূপের উপরে রাখা হয়, এতে একটি ম্যালোক অপারেশন প্রয়োজন। পরিশেষে, আমি আশা করি মেমরি পয়েন্টারটি একটি নতুন ঠিকানা হবে, এমনকি যদি ভেরিয়েবল রেফারেন্স এটি কোনও স্থানের পরিবর্তনের মতো দেখায়। সুতরাং, সত্যিই, কোন পার্থক্য আছে?
রবিন কো

79

আপনি যদি কেবল পথের সাথে সংযোগ দিচ্ছেন তবে আপনি রুবির নিজস্ব ফাইল.জাইন পদ্ধতি ব্যবহার করতে পারেন।

source = File.join(ROOT_DIR, project, 'App.config')

5
এটি এখন পর্যন্ত যাওয়ার পথ বলে মনে হচ্ছে ততক্ষণে রুবি বিভিন্ন পাথ বিভাজক সহ সিস্টেমে সঠিক স্ট্রিং তৈরির যত্ন নেবে।
পিইজেড

26

থেকে http://greyblake.com/blog/2012/09/02/ruby-perfomance-tricks/

<<উফ ব্যবহার করা concatতার চেয়ে অনেক বেশি দক্ষ +=, কারণ পরবর্তীকালে একটি অস্থায়ী বস্তু তৈরি হয় এবং নতুন বস্তুর সাথে প্রথম বস্তুকে ওভাররাইড করে।

require 'benchmark'

N = 1000
BASIC_LENGTH = 10

5.times do |factor|
  length = BASIC_LENGTH * (10 ** factor)
  puts "_" * 60 + "\nLENGTH: #{length}"

  Benchmark.bm(10, '+= VS <<') do |x|
    concat_report = x.report("+=")  do
      str1 = ""
      str2 = "s" * length
      N.times { str1 += str2 }
    end

    modify_report = x.report("<<")  do
      str1 = "s"
      str2 = "s" * length
      N.times { str1 << str2 }
    end

    [concat_report / modify_report]
  end
end

আউটপুট:

____________________________________________________________
LENGTH: 10
                 user     system      total        real
+=           0.000000   0.000000   0.000000 (  0.004671)
<<           0.000000   0.000000   0.000000 (  0.000176)
+= VS <<          NaN        NaN        NaN ( 26.508796)
____________________________________________________________
LENGTH: 100
                 user     system      total        real
+=           0.020000   0.000000   0.020000 (  0.022995)
<<           0.000000   0.000000   0.000000 (  0.000226)
+= VS <<          Inf        NaN        NaN (101.845829)
____________________________________________________________
LENGTH: 1000
                 user     system      total        real
+=           0.270000   0.120000   0.390000 (  0.390888)
<<           0.000000   0.000000   0.000000 (  0.001730)
+= VS <<          Inf        Inf        NaN (225.920077)
____________________________________________________________
LENGTH: 10000
                 user     system      total        real
+=           3.660000   1.570000   5.230000 (  5.233861)
<<           0.000000   0.010000   0.010000 (  0.015099)
+= VS <<          Inf 157.000000        NaN (346.629692)
____________________________________________________________
LENGTH: 100000
                 user     system      total        real
+=          31.270000  16.990000  48.260000 ( 48.328511)
<<           0.050000   0.050000   0.100000 (  0.105993)
+= VS <<   625.400000 339.800000        NaN (455.961373)

11

যেহেতু এটি এমন একটি পথ যেহেতু আমি সম্ভবত অ্যারে ব্যবহার করব এবং যোগদান করব:

source = [ROOT_DIR, project, 'App.config'] * '/'

9

এই सारটি দ্বারা অনুপ্রাণিত এখানে আরও একটি মানদণ্ড । এটি গতিশীল এবং পূর্বনির্ধারিত স্ট্রিংগুলির জন্য সংক্ষিপ্তকরণ ( +), সংযোজন ( <<) এবং ইন্টারপোলেশন ( #{}) তুলনা করে।

require 'benchmark'

# we will need the CAPTION and FORMAT constants:
include Benchmark

count = 100_000


puts "Dynamic strings"

Benchmark.benchmark(CAPTION, 7, FORMAT) do |bm|
  bm.report("concat") { count.times { 11.to_s +  '/' +  12.to_s } }
  bm.report("append") { count.times { 11.to_s << '/' << 12.to_s } }
  bm.report("interp") { count.times { "#{11}/#{12}" } }
end


puts "\nPredefined strings"

s11 = "11"
s12 = "12"
Benchmark.benchmark(CAPTION, 7, FORMAT) do |bm|
  bm.report("concat") { count.times { s11 +  '/' +  s12 } }
  bm.report("append") { count.times { s11 << '/' << s12 } }
  bm.report("interp") { count.times { "#{s11}/#{s12}"   } }
end

আউটপুট:

Dynamic strings
              user     system      total        real
concat    0.050000   0.000000   0.050000 (  0.047770)
append    0.040000   0.000000   0.040000 (  0.042724)
interp    0.050000   0.000000   0.050000 (  0.051736)

Predefined strings
              user     system      total        real
concat    0.030000   0.000000   0.030000 (  0.024888)
append    0.020000   0.000000   0.020000 (  0.023373)
interp    3.160000   0.160000   3.320000 (  3.311253)

উপসংহার: এমআরআই-তে প্রসারণ ভারী।


যেহেতু স্ট্রিংগুলি এখন অপরিবর্তনীয় হতে শুরু করেছে, আমি এর জন্য একটি নতুন মানদণ্ড দেখতে পছন্দ করব।
বিবস্থ

7

আমি পথের নাম ব্যবহার করতে পছন্দ করব:

require 'pathname' # pathname is in stdlib
Pathname(ROOT_DIR) + project + 'App.config'

প্রায় <<এবং+রুবি ডক্স থেকে:

+: নতুন ফিরিয়ে দেয় স্ট্রমে সংশ্লেষিত অন্যান্য_স্ট্রির সমন্বিত স্ট্রিং প্রদান করে

<<: প্রদত্ত বস্তুকে স্ট্রিমের সাথে সংযুক্ত করে। যদি 0 এবং 255 এর মধ্যে অবজেক্টটি ফিক্সনাম হয় তবে এটি কনটেনটেশনের আগে একটি অক্ষরে রূপান্তরিত হয়।

সুতরাং পার্থক্যটি প্রথম অপারেন্ডে পরিণত হয় ( <<স্থান পরিবর্তন করে, +নতুন স্ট্রিং ফিরিয়ে দেয় যাতে এটি মেমরির ভারী হয়) এবং যদি প্রথম অপারেন্ড ফিকনাম হয় তবে কী হবে ( <<সংখ্যার সমান কোডযুক্ত অক্ষরের সাথে যুক্ত +হবে, উত্থাপন করবে) ত্রুটি)


2
আমি শুধু আবিষ্কার করেছি যে + 'একটি পথনাম কলিং বিপজ্জনক কারন যদি ARG একটি সুনির্দিষ্ট পাথ হয়, রিসিভার পথ উপেক্ষা করা হয় হতে পারে: Pathname('/home/foo') + '/etc/passwd' # => #<Pathname:/etc/passwd>। এটি রুবডোক উদাহরণের উপর ভিত্তি করে ডিজাইন দ্বারা। ফাইল.জয়িন নিরাপদ বলে মনে হচ্ছে।
কেলভিন

আপনি (Pathname(ROOT_DIR) + project + 'App.config').to_sযদি স্ট্রিং অবজেক্টটি ফিরিয়ে দিতে চান তবে আপনাকে কল করতে হবে ।
lacostenycoder

6

আমাকে তার সাথে আমার সমস্ত অভিজ্ঞতা আপনাকে দেখাতে দিন।

আমার কাছে একটি কোয়েরি ছিল যা 32 কে রেকর্ড ফিরিয়েছিল, প্রতিটি রেকর্ডের জন্য আমি সেই পদ্ধতিটি ডেকেছিলাম যে ডাটাবেস রেকর্ডটিকে একটি কাঠামোযুক্ত স্ট্রিংয়ে ফর্ম্যাট করার জন্য এবং এটি একটি স্ট্রিংয়ের সাথে যুক্ত করে যে এই সমস্ত প্রক্রিয়া শেষে ডিস্কে একটি ফাইলে পরিণত হবে।

আমার সমস্যাটি ছিল রেকর্ডটি পেরিয়ে, প্রায় 24k এর মধ্যে, স্ট্রিংকে সংযুক্ত করার প্রক্রিয়াটি একটি ব্যথা চালু করে।

আমি নিয়মিত '+' অপারেটরটি ব্যবহার করে এটি করছিলাম।

আমি যখন '<<' এ পরিবর্তিত হয়েছি তখন ম্যাজিকের মতো ছিল। সত্যিই দ্রুত ছিল।

সুতরাং, আমি আমার পুরানো সময়গুলি মনে করি - 1998 এর সাজান - যখন আমি জাভা ব্যবহার করছিলাম এবং স্ট্রিংকে '+' ব্যবহার করে স্ট্রিংব্রফার (এবং এখন আমরা, জাভা বিকাশকারীদের স্ট্রিংবিল্ডার) রেখেছি।

আমি বিশ্বাস করি যে রুবি বিশ্বে + / << প্রক্রিয়াটি জাভা বিশ্বে + / স্ট্রিংবিল্ডার.অ্যাপেন্ডের মতো।

প্রথম স্মৃতিতে পুরো অবজেক্টটিকে পুনরায় গণনা করুন এবং অন্যটি একটি নতুন ঠিকানার দিকে নির্দেশ করুন।


5

কনটেনটেশন আপনি বলছেন? তাহলে কীভাবে #concatপদ্ধতি?

a = 'foo'
a.object_id #=> some number
a.concat 'bar' #=> foobar
a.object_id #=> same as before -- string a remains the same object

সমস্ত ন্যায্যতা concatহিসাবে , aliesated হয় <<


7
আঠালো স্ট্রিংয়ের আরও একটি উপায় রয়েছে যা অন্যেরা উল্লেখ করেন নি, এবং এটি হ'ল সংক্ষিপ্তসার দ্বারা:"foo" "bar" 'baz" #=> "foobarabaz"
বোরিস স্ট্যাটনিকিকি

অন্যদের জন্য নোট: এটি একক উদ্ধৃতি বলে মনে করা হয় না, তবে বাকীগুলির মতো একটি দ্বিগুণ। ঝরঝরে পদ্ধতি!
জোশুয়া পিন্টার


2

আপনি %নিম্নলিখিত হিসাবে ব্যবহার করতে পারেন :

source = "#{ROOT_DIR}/%s/App.config" % project

এই পদ্ধতির 'পাশাপাশি (একক) উদ্ধৃতি চিহ্নও কাজ করে ।


2

আপনি ব্যবহার করতে পারেন +বা <<অপারেটর রাখতে পারেন , তবে রুবি .concatফাংশনে সবচেয়ে বেশি পছন্দনীয় কারণ এটি অন্যান্য অপারেটরের তুলনায় অনেক দ্রুত। আপনি এটি ব্যবহার করতে পারেন।

source = "#{ROOT_DIR}/".concat(project.concat("/App.config"))

আমি মনে করি .আপনার শেষ concatনং পরে একটি অতিরিক্ত আছে ?
lacostenycoder

1

পরিস্থিতি সম্পর্কিত বিষয়গুলি উদাহরণস্বরূপ:

# this will not work
output = ''

Users.all.each do |user|
  output + "#{user.email}\n"
end
# the output will be ''
puts output

# this will do the job
output = ''

Users.all.each do |user|
  output << "#{user.email}\n"
end
# will get the desired output
puts output

প্রথম উদাহরণে, +অপারেটরের সাথে সম্মিলিতভাবে outputঅবজেক্টটি আপডেট হবে না , তবে দ্বিতীয় উদাহরণে <<অপারেটর outputপ্রতিটি পুনরাবৃত্তির সাথে অবজেক্টটি আপডেট করবে । সুতরাং, উপরের ধরণের পরিস্থিতিটি <<আরও ভাল।


1

আপনি স্ট্রিং সংজ্ঞাটিতে সরাসরি জড়িত করতে পারেন:

nombre_apellido = "#{customer['first_name']} #{customer['last_name']} #{order_id}"

0

আপনার নির্দিষ্ট ক্ষেত্রে আপনি Array#joinফাইল পাথ ধরণের স্ট্রিং তৈরি করার সময়ও ব্যবহার করতে পারেন :

string = [ROOT_DIR, project, 'App.config'].join('/')]

বিভিন্ন ধরণের স্ট্রাইটে স্বয়ংক্রিয়ভাবে রূপান্তরিত করার এটির একটি মনোরম পার্শ্ব প্রতিক্রিয়া রয়েছে:

['foo', :bar, 1].join('/')
=>"foo/bar/1"

0

পুতুলের জন্য:

$username = 'lala'
notify { "Hello ${username.capitalize}":
    withpath => false,
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.