LINUX.ORG.RU

Динамическое создание символов минуя стадию строк.

 


0

5

Например

a = 1
b = 2
"#{a}_#{b}".to_sym
создаст символ, но прежде оно создаст стринг, потратит на это время и память, можно ли этого избежать (особенно учитывая, что символы существуют как раз ради экономии времени и памяти)?

Где тег «хочется странного»?

Зачем использовать в этом случае символ вместо строки? Для того, чтобы память потекла?

Создание символа более затратно, чем создание строки. Кроме того, преждевременная оптимизация — смертный грех.

Anatolik ★★
()
Ответ на: комментарий от anonymous

Хвалю.

Попытка адептов недоЯП оптимизировать настолько милы. Они как дети, которая не понимают, что каждая байдень в их ЯП даёт десятикратный оверхед, но доблесные оптимизаторы не сдаются. Они из 100кратного оверхеда сделают 99кратный и будут рады.

superhackkiller1997
()

Символы существуют не ради экономии времени и памяти (кто вообще будет использовать руби там, где время и память ограничена?), а потому, что семантика у них отличается от строк.

anonymous
()

Согласен с ораторами:
в руби «Symbol» нисколько не выгоднее «String». Возможно, ты путаешь с Дельфи, где символьные переменные преобразуются компилятором в целые числа.

В руби и то и другое хранит целые строки.

Если хочешь скорости, то вместо хэша с символом:

person = {}
person['FirstName'] = 'Иван'
person['LastName'] = 'Сидоров'

используй массив с индексом:

PI_FirstName = 0
PI_LastName  = 1
person = []
person[PI_FirstName] = 'Иван'
person[PI_LastName] = 'Сидоров'

В этом случае индексы действительно представляют из себя целые числа Fixnum и занимают 4 байта.
Выемка данных происходит мгновенно. Я всё время так делаю в «узких» местах.

Novator ★★★★★
()
Ответ на: комментарий от Deleted

В динамическом языке все должно быть динамическим, я уж сам постараюсь на отстреливать себе ногу.

special-k ★★★
() автор топика

Я осилил benchmark)))

require 'benchmark'

a = []
1000.times.each{|i|
  a[i] ||= []
  1000.times.each{|j|
    a[i][j] = 1
  }
}

h = {}
1000.times.each{|i|
  1000.times.each{|j|
    h["#{i}_#{j}"] = 1
  }
}

o = {}
1000.times.each{|i|
  1000.times.each{|j|
    o["#{i}_#{j}".to_sym] = 1
  }
}

x = 888; y = 888
k = "#{x}_#{y}"
s = "#{x}_#{y}".to_sym

n = 1000000
Benchmark.bm(3) do |b|
  b.report("array   :"){ n.times{ a[x][y] } }
  b.report("hash    :"){ n.times{ h[k] } }
  b.report("sym hash:"){ n.times{ o[s] } }
end
          user     system      total        real
array   :  0.100000   0.000000   0.100000 (  0.109684)
hash    :  0.150000   0.000000   0.150000 (  0.147242)
sym hash:  0.100000   0.000000   0.100000 (  0.097119)
Как видите, символьный хэш одинаков по скорости с массивом. При этом, с ним гораздо меньше мороки - не нужно создавать массив под каждую строку.

special-k ★★★
() автор топика
Ответ на: комментарий от Anatolik

Создание символа более затратно, чем создание строки.

Нет, создания символа происходит один раз, создание строки каждый раз.

superhackkiller1997

Попытка адептов недоЯП оптимизировать настолько милы.

Твоя попытка написать предложение гораздо милее))

special-k ★★★
() автор топика
Ответ на: комментарий от geekless

не является, просто, зачем мне эта лишняя операция.. это не красиво..

special-k ★★★
() автор топика
Ответ на: комментарий от special-k

Твоя попытка написать предложение гораздо милее))

Твоя попытка съослить потерпела фиско, ибо предложение не пишут.

superhackkiller1997
()

Нет, ну давайте посмотрим на ситуацию шире

  • хочется поместить объекты в хэш (в одномерную структуру)
  • хочется создать «эффект» многомерности
  • хочется, чтобы это работало быстрее и экономичнее, чем хэш со строками в ключах
  • хочется оставить возможность ручной выборки (типа выбрать 3-ий слева, 5-ый сверху элемент)
  • ок-ок, хочется странного))
special-k ★★★
() автор топика
Последнее исправление: special-k (всего исправлений: 1)
Ответ на: комментарий от Deleted

Еще нет, вот когда я начну конвертировать данные юзера в символы, как это делалось давеча в рельсах, вот тогда да))

special-k ★★★
() автор топика
Ответ на: комментарий от special-k

Хоть свои. Проблема в том, что (AFAIR) память, выделенная под символы, не освободится до окончания программы. А раз ты генерируешь их динамически… :3

Deleted
()
Ответ на: комментарий от Deleted

Я помню об этом каждую секунду) Это не применимо к потоку данных, но применимо к ограниченному количеству данных. Проблема в том, что память под любые другие объекты так же выделяется! при этом, (если мы говорим про строки), она выделяется каждый раз, а затем, этот каждый раз будет удаляться из памяти, и на это будет уходить дополнительное время. В моем случае этих символов будет мало, примерно 500-1к. А вот аналогичных по строению хэшей будет много.. 500-1к.

special-k ★★★
() автор топика
Ответ на: комментарий от special-k

Я бы может и некоторые другие объекты пометил бы как неудаляемые, если бы была такая возможность, чтобы интерпретатор не тратил время на их проверку. Хотя.. это слишком геморройно уже.. лучше сосредоточится на задаче.

special-k ★★★
() автор топика
Последнее исправление: special-k (всего исправлений: 1)
Ответ на: комментарий от superhackkiller1997

Попытка адептов недоЯП оптимизировать настолько милы. Они как дети, которая не понимают, что каждая байдень в их ЯП даёт десятикратный оверхед, но доблесные оптимизаторы не сдаются. Они из 100кратного оверхеда сделают 99кратный и будут рады.

О Великий Гуру, Учитель ПравильныхЯП, ты окрыл мне глаза! Я брошу всё и куплю себе учебник ассемблера, уйду в горный монастырь и через 10 лет напишу эффективный код, который я был написал на руби за неделю с оверхедом, на который всем насрать.

Alve ★★★★★
()
Ответ на: комментарий от superhackkiller1997

Ты напишешь код быстрее меня?

А я разве что-то говорил про тебя? Про соревнование в скорости написания кода? Вроде нет.

Alve ★★★★★
()
Ответ на: комментарий от Alve

Ну быстрее ни в каком смысле ты не напишешь, а зачем ты начинаешь про скорость чего-то там гвоорить?

Ты намекаешь на то, что я типа проповедую асмзатвор и запилил чего-то за 10лет, а ты типа такой шустрый, дерзкий, быстрый.

А теперь скажи в чем смысл твоего твоего ололо, когда я возьму и напишу твоё «рубизанеделю» за неделю и не получу 10кратных оверхедов? В чём, так сказать, профит?

superhackkiller1997
()
Ответ на: комментарий от cdshines

Скорее меня не изнасиловал пхппешник/жабист/рубист и ООПшник головного мозга с мистической верой в то, что на сишке писать медленнее, а на оверхед можно класть.

Возможно я что-то не понимаю в этом мире, а так да, возможно.

superhackkiller1997
()
Ответ на: комментарий от cdshines

А ещё вера в то, что писать на ассемблере долго, когда там есть такие фичи, о которох возможно только какие-нибудь вменяемые диалекты лиспам лишь могут.

superhackkiller1997
()
Ответ на: комментарий от cdshines

Дак я не против, но ты смотри на его аргументы - он говорит, что выбрал руби не потому, что оно ему нравится, а ибо быстрее, хотя он наврал. Зачем он врёт?

Если бы он написал что-то, аля «а мне нравится» - я бы ему слово не сказал, но он начал вещать из свох догматов, которые я не люблю.

superhackkiller1997
()
Ответ на: комментарий от superhackkiller1997

ну вообще-то, это так. чтобы писать на си быстро, как ты (по твоим словам), нужно заниматься им столько, сколько ты. У него выше порог вхождения (хотя после порога и знания качественнее), он содержит ненужные для многих случаев вещи (не могу придумать, зачем, например, в рельсах бы указатели пригодились) и т. д. Каждому свое. Если я пишу на руби быстрее, чем на си, то это не значит, что тебе надо говорить мне, что ты пишешь на си быстрее меня.

cdshines ★★★★★
()
Ответ на: комментарий от cdshines

Дак зачем нагло врать про быстро, если это не правда? Скажи - мне нравится си, я пишу на нём лучше всего и быстрее - мне проще. Повторюсь.

Он нагло съиронизировал юзая общественный шаблон, чтобы показать какой я ололоша, а потом съехал на то, что он типа говорил про себя.

Только вот я говорил не про него, и его сообщение не имеет смысла, как ответ мне.

superhackkiller1997
()
Ответ на: комментарий от superhackkiller1997

когда я возьму и напишу

Обидели школьника, не дали померятся пиписьками? Я не знаю твой настоящий возраст, но стремление всем вокруг доказать что-то и соревноваться точно соответствует 9-10 классу. *ушёл из треда.

Alve ★★★★★
()
Ответ на: комментарий от special-k

вот оно)

Это ведь просто сахар для to_sym. Стадию строки оно не минует.

Нет, создания символа происходит один раз, создание строки каждый раз.

Это не отменяет того, что создание символа будет более затратным, чем создание строки:

require 'benchmark'
require 'ffaker'

n = 2000000
Benchmark.bmbm do |x|
  x.report('string') do
    n.times { "#{Faker::Name.name}_#{rand(2)}" }
  end
  x.report('symbol') do
    n.times { "#{Faker::Name.name}_#{rand(2)}".to_sym }
  end
  x.report('sugar_symbol') do
    n.times { :"#{Faker::Name.name}_#{rand(2)}" }
  end
end

Rehearsal ------------------------------------------------
string         9.910000   0.010000   9.920000 (  9.938621)
symbol        16.540000   0.190000  16.730000 ( 16.785586)
sugar_symbol  18.270000   0.170000  18.440000 ( 18.458267)
-------------------------------------- total: 45.090000sec

                   user     system      total        real
string         8.950000   0.080000   9.030000 (  9.029096)
symbol        16.350000   0.070000  16.420000 ( 16.489534)
sugar_symbol  18.470000   0.060000  18.530000 ( 18.571173)

Как видите, символьный хэш одинаков по скорости с массивом.

У меня — нет:

          user     system      total        real
array   :  0.130000   0.000000   0.130000 (  0.127917)
hash    :  0.220000   0.000000   0.220000 (  0.222584)
sym hash:  0.160000   0.000000   0.160000 (  0.157841)
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-linux]

Я помню об этом каждую секунду)

Ох. Предрекаю вам увеселительное времяпрепровождение, если вы где-то за чем-то не уследите.

Лучше напишите красиво со строками, а потом, если не будет устраивать производительность, последуйте всегда безопасному совету Novator'a.

Anatolik ★★
()
Ответ на: комментарий от Anatolik

Это ведь просто сахар для to_sym

да, только для intern :\ Пичаль, я надеялся, что оно обходит создание объекта строки..

создание символа будет более затратным

Изначально, суть в том, чтобы избегать создания новых символов, и иметь ограниченное число их. Т.е символы могут создаваться сколь угодно долго, если они будут создаваться только раз, а вызов значения символа уже будет быстрее чем создание нового объекта, но в настоящий момент это невозможно, т.к. созданию динамического символа предшествует создание строки.

Т.о. делать ключи на основе динамически создаваемых символов, сейчас, не имеет смысла.

символьный хэш одинаков по скорости с массивом

У меня — нет

Да практически, к тому же, у меня речь шла про имитацию с помощью ключей двумерного (и более, но мне сейчас нужен двумерный).

Вообще, руби хорош тем, что, например, скорости работы массива и хэша практически одинаковы, в отличии он того же js (особенно v8). Другое дело, что я хотел избавиться от постоянной генерации объектов ключей, при реализации эффекта многомерности через ключ.

special-k ★★★
() автор топика

потратит на это время и память
ради экономии времени и памяти
ruby

разрыдался

vasily_pupkin ★★★★★
()
Ответ на: комментарий от anonymous

Си не может работать быстрее чем руби, руби сам написан на си..

special-k ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.